[mpich2-dev] [PATCH 1/1] Issue 4882: Fix assertions when negative displacements are used in datatypes
Jeff Parker
jjparker at us.ibm.com
Tue Apr 22 11:13:42 CDT 2008
This patch contains a fix for problems with the BG/P MPI_Aint changes previously posted, as follows:
1. Some functions in bgp/comm/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c have displacements in buffer pointers. The MPI_Aint changes that I previously made added assertions to ensure that arithmetic on buffer pointers does not overflow beyond the size of a pointer, and added casting of buffer pointers to MPI_Aints. These changes are not correct when the buffer pointers contain negative offsets, and therefore have been removed.
2. The MPI_Aint configurable variables were using (long) and (unsigned long) as the arithmetic version of a pointer. I changed these to use the new MPI_Pint and MPI_Puint datatypes. This will generate the same code, but is the proper way to do this.
Signed-off-by: Jeff Parker <jjparker at us.ibm.com>
---
lib/mpi/mpich2/configure.in | 36 +++---
lib/mpi/mpich2/src/include/mpi.h.in | 1 +
lib/mpi/mpich2/src/include/mpiutil.h | 2 +-
.../mpid/common/datatype/dataloop/segment_ops.c | 124 ++++++++++++++------
4 files changed, 109 insertions(+), 54 deletions(-)
diff --git a/lib/mpi/mpich2/configure.in b/lib/mpi/mpich2/configure.in
index 2640d26..18f3938 100755
--- a/lib/mpi/mpich2/configure.in
+++ b/lib/mpi/mpich2/configure.in
@@ -5003,6 +5003,24 @@ MPI_PUINT="unsigned $MPI_AINT"
AC_SUBST(MPI_PINT)
AC_SUBST(MPI_PUINT)
+# Set:
+# - MPI_AINT cast to a void*
+MPI_AINT_CAST_TO_VOID_PTR="(void*)(MPI_Pint)"
+# - void* cast to an MPI_AINT
+MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(MPI_Puint)"
+# - void* containing a signed displacement cast to an MPI_AINT
+MPI_PTR_DISP_CAST_TO_MPI_AINT="(MPI_Aint)(MPI_Pint)"
+# - MPI_AINT cast to a long long for printing
+MPI_AINT_CAST_TO_LONG_LONG="(long long)"
+export MPI_AINT_CAST_TO_VOID_PTR
+export MPI_VOID_PTR_CAST_TO_MPI_AINT
+export MPI_PTR_DISP_CAST_TO_MPI_AINT
+export MPI_AINT_CAST_TO_LONG_LONG
+AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
+AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
+AC_SUBST(MPI_PTR_DISP_CAST_TO_MPI_AINT)
+AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
+
if test "$with_aint_size" == "0" ; then
# use default size
AC_MSG_RESULT([Default MPI_Aint $with_aint_size $MPI_SIZEOF_AINT])
@@ -5018,40 +5036,22 @@ if test "$with_aint_size" == "8" ; then
MPI_AINT_FMT_DEC_SPEC="%lld"
MPI_AINT_FMT_HEX_SPEC="%#llx"
- MPI_AINT_CAST_TO_VOID_PTR="(void*)(long)"
- MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(unsigned long)"
- MPI_AINT_CAST_TO_LONG_LONG="(long long)"
AC_DEFINE(HAVE_AINT_LARGER_THAN_FINT,1,[Define if addresses are larger than Fortran integers])
export MPI_SIZEOF_AINT
export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC
- export MPI_AINT_CAST_TO_VOID_PTR
- export MPI_VOID_PTR_CAST_TO_MPI_AINT
- export MPI_AINT_CAST_TO_LONG_LONG
AC_SUBST(MPI_AINT)
AC_SUBST(MPI_AINT_FMT_DEC_SPEC)
AC_SUBST(MPI_AINT_FMT_HEX_SPEC)
- AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
- AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
- AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
else
# use calculated MPI_Aint values
AC_MSG_RESULT([Use configured MPI_Aint $with_aint_size])
- MPI_AINT_CAST_TO_VOID_PTR="(void*)"
- MPI_VOID_PTR_CAST_TO_MPI_AINT="(MPI_Aint)(unsigned long)"
- MPI_AINT_CAST_TO_LONG_LONG="(long long)(unsigned long)"
export MPI_SIZEOF_AINT
export MPI_AINT_FMT_DEC_SPEC MPI_AINT_FMT_HEX_SPEC
- export MPI_AINT_CAST_TO_VOID_PTR
- export MPI_VOID_PTR_CAST_TO_MPI_AINT
- export MPI_AINT_CAST_TO_LONG_LONG
AC_SUBST(MPI_AINT)
AC_SUBST(MPI_AINT_FMT_DEC_SPEC)
AC_SUBST(MPI_AINT_FMT_HEX_SPEC)
- AC_SUBST(MPI_AINT_CAST_TO_VOID_PTR)
- AC_SUBST(MPI_VOID_PTR_CAST_TO_MPI_AINT)
- AC_SUBST(MPI_AINT_CAST_TO_LONG_LONG)
fi
# If sizeof(mpi_aint) = sizeof(int), set this value
diff --git a/lib/mpi/mpich2/src/include/mpi.h.in b/lib/mpi/mpich2/src/include/mpi.h.in
index b275bb7..d623a5e 100644
--- a/lib/mpi/mpich2/src/include/mpi.h.in
+++ b/lib/mpi/mpich2/src/include/mpi.h.in
@@ -336,6 +336,7 @@ typedef @MPI_FINT@ MPI_Fint;
#define MPI_AINT_FMT_HEX_SPEC "@MPI_AINT_FMT_HEX_SPEC@"
#define MPI_AINT_CAST_TO_VOID_PTR @MPI_AINT_CAST_TO_VOID_PTR@
#define MPI_VOID_PTR_CAST_TO_MPI_AINT @MPI_VOID_PTR_CAST_TO_MPI_AINT@
+#define MPI_PTR_DISP_CAST_TO_MPI_AINT @MPI_PTR_DISP_CAST_TO_MPI_AINT@
#define MPI_AINT_CAST_TO_LONG_LONG @MPI_AINT_CAST_TO_LONG_LONG@
/* Let ROMIO know that MPI_Offset is already defined */
diff --git a/lib/mpi/mpich2/src/include/mpiutil.h b/lib/mpi/mpich2/src/include/mpiutil.h
index 9df215c..bb9e550 100644
--- a/lib/mpi/mpich2/src/include/mpiutil.h
+++ b/lib/mpi/mpich2/src/include/mpiutil.h
@@ -105,6 +105,6 @@ int MPID_Abort( struct MPID_Comm *comm, int mpi_errno, int exit_code, const char
* \param[in] aint Variable of type MPI_Aint
*/
#define MPID_Ensure_Aint_fits_in_pointer( aint ) \
- MPIU_Assert( (aint) == (MPI_Aint)(unsigned long) MPI_AINT_CAST_TO_VOID_PTR (aint) );
+ MPIU_Assert( (aint) == (MPI_Aint)(MPI_Puint) MPI_AINT_CAST_TO_VOID_PTR (aint) );
#endif /* !defined(MPIUTIL_H_INCLUDED) */
diff --git a/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c b/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c
index 6fe799f..c7e5473 100644
--- a/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c
+++ b/lib/mpi/mpich2/src/mpid/common/datatype/dataloop/segment_ops.c
@@ -37,6 +37,7 @@ int PREPEND_PREFIX(Segment_contig_m2m)(DLOOP_Offset *blocks_p,
if (paramp->direction == DLOOP_M2M_TO_USERBUF) {
/* Ensure that pointer increment fits in a pointer */
+ /* userbuf is a pointer (not a displacement) since it is being used on a memcpy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
memcpy((char *) MPI_AINT_CAST_TO_VOID_PTR ((MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off),
paramp->streambuf,
@@ -44,11 +45,14 @@ int PREPEND_PREFIX(Segment_contig_m2m)(DLOOP_Offset *blocks_p,
}
else {
/* Ensure that pointer increment fits in a pointer */
+ /* userbuf is a pointer (not a displacement) since it is being used on a memcpy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
memcpy(paramp->streambuf,
(char *) ( MPI_AINT_CAST_TO_VOID_PTR ((MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off) ),
size);
}
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it was used on a memcpy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) + size );
paramp->streambuf += size;
return 0;
@@ -76,6 +80,7 @@ int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
char *cbufp;
/* Ensure that pointer increment fits in a pointer */
+ /* userbuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off );
cbufp = (char*)( MPI_AINT_CAST_TO_VOID_PTR ( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) + rel_off ) );
DLOOP_Handle_get_size_macro(el_type, el_size);
@@ -109,6 +114,8 @@ int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
else {
for (i=0; i < whole_count; i++) {
memcpy(cbufp, paramp->streambuf, ((DLOOP_Offset)blksz) * el_size);
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
((DLOOP_Offset)blksz) * el_size );
paramp->streambuf += ((DLOOP_Offset)blksz) * el_size;
@@ -118,6 +125,8 @@ int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
}
if (blocks_left) {
memcpy(cbufp, paramp->streambuf, ((DLOOP_Offset)blocks_left) * el_size);
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
((DLOOP_Offset)blocks_left) * el_size );
paramp->streambuf += ((DLOOP_Offset)blocks_left) * el_size;
@@ -150,6 +159,8 @@ int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
else {
for (i=0; i < whole_count; i++) {
memcpy(paramp->streambuf, cbufp, (DLOOP_Offset)blksz * el_size);
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
(DLOOP_Offset)blksz * el_size );
paramp->streambuf += (DLOOP_Offset)blksz * el_size;
@@ -157,6 +168,8 @@ int PREPEND_PREFIX(Segment_vector_m2m)(DLOOP_Offset *blocks_p,
}
if (blocks_left) {
memcpy(paramp->streambuf, cbufp, (DLOOP_Offset)blocks_left * el_size);
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
(DLOOP_Offset)blocks_left * el_size );
paramp->streambuf += (DLOOP_Offset)blocks_left * el_size;
@@ -191,6 +204,8 @@ int PREPEND_PREFIX(Segment_blkidx_m2m)(DLOOP_Offset *blocks_p,
DLOOP_Assert(curblock < count);
+ /* Ensure that pointer increment fits in a pointer */
+ /* userbuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) +
rel_off + offsetarray[curblock] );
cbufp = (char*) MPI_AINT_CAST_TO_VOID_PTR
@@ -226,6 +241,8 @@ int PREPEND_PREFIX(Segment_blkidx_m2m)(DLOOP_Offset *blocks_p,
memcpy(dest, src, (DLOOP_Offset)blocklen * el_size);
}
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
(DLOOP_Offset)blocklen * el_size );
paramp->streambuf += (DLOOP_Offset)blocklen * el_size;
@@ -262,6 +279,7 @@ int PREPEND_PREFIX(Segment_index_m2m)(DLOOP_Offset *blocks_p,
cur_block_sz = blockarray[curblock];
/* Ensure that pointer increment fits in a pointer */
+ /* userbuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->userbuf)) +
rel_off + offsetarray[curblock]);
cbufp = (char*) MPI_AINT_CAST_TO_VOID_PTR
@@ -297,6 +315,8 @@ int PREPEND_PREFIX(Segment_index_m2m)(DLOOP_Offset *blocks_p,
memcpy(dest, src, cur_block_sz * el_size);
}
+ /* Ensure that pointer increment fits in a pointer */
+ /* streambuf is a pointer (not a displacement) since it is being used for a memory copy */
MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (paramp->streambuf)) +
cur_block_sz * el_size );
paramp->streambuf += cur_block_sz * el_size;
@@ -612,14 +632,20 @@ static int DLOOP_Segment_contig_mpi_flatten(DLOOP_Offset *blocks_p,
last_idx = paramp->index - 1;
if (last_idx >= 0) {
- MPID_Ensure_Aint_fits_in_pointer( paramp->disps[last_idx] + ((DLOOP_Offset)paramp->blklens[last_idx]) );
- last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
+ /* Since disps can be negative, we cannot use MPID_Ensure_Aint_fits_in_pointer to verify that
+ * disps + blklens fits in a pointer. Just let it truncate, if the sizeof a pointer is less
+ * than the sizeof an MPI_Aint.
+ */
+ last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
(paramp->disps[last_idx] + ((DLOOP_Offset)paramp->blklens[last_idx]));
}
- MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT (bufp)) + rel_off);
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits in a pointer.
+ * Just let it truncate.
+ */
if ((last_idx == paramp->length-1) &&
- (last_end != ((char *) bufp + rel_off)))
+ (last_end != ((char *) bufp + rel_off)))
{
/* we have used up all our entries, and this region doesn't fit on
* the end of the last one. setting blocks to 0 tells manipulation
@@ -634,7 +660,11 @@ static int DLOOP_Segment_contig_mpi_flatten(DLOOP_Offset *blocks_p,
paramp->blklens[last_idx] += size;
}
else {
- paramp->disps[last_idx+1] = MPI_VOID_PTR_CAST_TO_MPI_AINT ((char *) bufp + rel_off);
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a pointer. Just let it
+ * sign extend.
+ */
+ paramp->disps[last_idx+1] = MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off;
paramp->blklens[last_idx+1] = size;
paramp->index++;
}
@@ -689,17 +719,22 @@ static int DLOOP_Segment_vector_mpi_flatten(DLOOP_Offset *blocks_p,
last_idx = paramp->index - 1;
if (last_idx >= 0) {
- MPID_Ensure_Aint_fits_in_pointer( paramp->disps[last_idx] +
- (MPI_Aint)(paramp->blklens[last_idx]) );
- last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
+ /* Since disps can be negative, we cannot use MPID_Ensure_Aint_fits_in_pointer to verify that
+ * disps + blklens fits in a pointer. Nor can we use MPI_AINT_CAST_TO_VOID_PTR to cast the
+ * sum to a pointer. Just let it truncate, if the sizeof a pointer is less than the sizeof
+ * an MPI_Aint.
+ */
+ last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
( paramp->disps[last_idx] +
(MPI_Aint)(paramp->blklens[last_idx]) );
}
- MPID_Ensure_Aint_fits_in_pointer( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off );
- if ((last_idx == paramp->length-1) &&
- (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
- ( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ) )
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits in a pointer.
+ * Just let it truncate.
+ */
+ if ((last_idx == paramp->length-1) &&
+ (last_end != ((char *) bufp + rel_off)))
{
/* we have used up all our entries, and this one doesn't fit on
* the end of the last one.
@@ -712,14 +747,17 @@ static int DLOOP_Segment_vector_mpi_flatten(DLOOP_Offset *blocks_p,
#endif
return 1;
}
- else if (last_idx >= 0 && (last_end == (char *) MPI_AINT_CAST_TO_VOID_PTR
- ( MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off ) ) )
+ else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))
{
/* add this size to the last vector rather than using up new one */
paramp->blklens[last_idx] += size;
}
else {
- paramp->disps[last_idx+1] = MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off;
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a pointer. Just let it
+ * sign extend.
+ */
+ paramp->disps[last_idx+1] = MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off;
paramp->blklens[last_idx+1] = size;
paramp->index++;
}
@@ -773,15 +811,21 @@ static int DLOOP_Segment_blkidx_mpi_flatten(DLOOP_Offset *blocks_p,
last_idx = paramp->index - 1;
if (last_idx >= 0) {
- MPID_Ensure_Aint_fits_in_pointer( paramp->disps[last_idx] + ((DLOOP_Offset)paramp->blklens[last_idx]) );
- last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
+ /* Since disps can be negative, we cannot use MPID_Ensure_Aint_fits_in_pointer to verify that
+ * disps + blklens fits in a pointer. Nor can we use MPI_AINT_CAST_TO_VOID_PTR to cast the
+ * sum to a pointer. Just let it truncate, if the sizeof a pointer is less than the sizeof
+ * an MPI_Aint.
+ */
+ last_end = (char*) MPI_AINT_CAST_TO_VOID_PTR
(paramp->disps[last_idx] + ((DLOOP_Offset)paramp->blklens[last_idx]));
}
- MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off );
- if ((last_idx == paramp->length-1) &&
- (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
- (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ))
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits in a pointer.
+ * Just let it truncate.
+ */
+ if ((last_idx == paramp->length-1) &&
+ (last_end != ((char *) bufp + rel_off)))
{
/* we have used up all our entries, and this one doesn't fit on
* the end of the last one.
@@ -794,15 +838,17 @@ static int DLOOP_Segment_blkidx_mpi_flatten(DLOOP_Offset *blocks_p,
#endif
return 1;
}
- else if (last_idx >= 0 && (last_end == (char *) MPI_AINT_CAST_TO_VOID_PTR
- (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ) )
+ else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))
{
/* add this size to the last vector rather than using up new one */
paramp->blklens[last_idx] += size;
}
else {
- paramp->disps[last_idx+1] = (MPI_Aint) (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp +
- rel_off + offsetarray[last_idx+1]);
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a pointer. Just let it
+ * sign extend.
+ */
+ paramp->disps[last_idx+1] = MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off + offsetarray[last_idx+1];
paramp->blklens[last_idx+1] = size;
paramp->index++;
}
@@ -856,17 +902,22 @@ static int DLOOP_Segment_index_mpi_flatten(DLOOP_Offset *blocks_p,
last_idx = paramp->index - 1;
if (last_idx >= 0) {
- MPID_Ensure_Aint_fits_in_pointer( paramp->disps[last_idx] +
- (MPI_Aint)(paramp->blklens[last_idx]) );
- last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
+ /* Since disps can be negative, we cannot use MPID_Ensure_Aint_fits_in_pointer to verify that
+ * disps + blklens fits in a pointer. Nor can we use MPI_AINT_CAST_TO_VOID_PTR to cast the
+ * sum to a pointer. Just let it truncate, if the sizeof a pointer is less than the sizeof
+ * an MPI_Aint.
+ */
+ last_end = (char *) MPI_AINT_CAST_TO_VOID_PTR
( paramp->disps[last_idx] +
(MPI_Aint)(paramp->blklens[last_idx]) );
}
- MPID_Ensure_Aint_fits_in_pointer( (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off );
- if ((last_idx == paramp->length-1) &&
- (last_end != (char *) MPI_AINT_CAST_TO_VOID_PTR
- (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ))
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPID_Ensure_Aint_fits_in_pointer to ensure the sum fits in a pointer.
+ * Just let it truncate.
+ */
+ if ((last_idx == paramp->length-1) &&
+ (last_end != ((char *) bufp + rel_off)))
{
/* we have used up all our entries, and this one doesn't fit on
* the end of the last one.
@@ -879,14 +930,17 @@ static int DLOOP_Segment_index_mpi_flatten(DLOOP_Offset *blocks_p,
#endif
return 1;
}
- else if (last_idx >= 0 && (last_end == (char *) MPI_AINT_CAST_TO_VOID_PTR
- (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp + rel_off) ))
+ else if (last_idx >= 0 && (last_end == ((char *) bufp + rel_off)))
{
/* add this size to the last vector rather than using up new one */
paramp->blklens[last_idx] += size;
}
else {
- paramp->disps[last_idx+1] = (MPI_VOID_PTR_CAST_TO_MPI_AINT bufp) + rel_off + offsetarray[last_idx+1];
+ /* Since bufp can be a displacement and can be negative, we cannot use
+ * MPI_VOID_PTR_CAST_TO_MPI_AINT to cast the sum to a pointer. Just let it
+ * sign extend.
+ */
+ paramp->disps[last_idx+1] = MPI_PTR_DISP_CAST_TO_MPI_AINT bufp + rel_off + offsetarray[last_idx+1];
paramp->blklens[last_idx+1] = size;
paramp->index++;
}
--
1.5.3.7
More information about the mpich2-dev
mailing list