diff --git a/.github/workflows/icc/Dockerfile.ci b/.github/workflows/icc/Dockerfile.ci index 743044944385..ece1570cfbad 100644 --- a/.github/workflows/icc/Dockerfile.ci +++ b/.github/workflows/icc/Dockerfile.ci @@ -1,12 +1,12 @@ -FROM ubuntu:20.04 +FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update -y \ - && apt-get install -y cmake ccache libproj-dev wget python3-dev python3-numpy python3-pip swig + && apt-get install -y cmake gcc ccache libproj-dev wget python3-dev python3-numpy python3-pip swig -RUN wget https://registrationcenter-download.intel.com/akdlm/irc_nas/18717/l_dpcpp-cpp-compiler_p_2022.1.0.137_offline.sh \ - && sh l_dpcpp-cpp-compiler_p_2022.1.0.137_offline.sh -a -s --eula accept +RUN wget https://registrationcenter-download.intel.com/akdlm/IRC_NAS/bb99984f-370f-413d-bbec-38928d2458f2/l_dpcpp-cpp-compiler_p_2024.0.2.29_offline.sh \ + && sh l_dpcpp-cpp-compiler_p_2024.0.2.29_offline.sh -a -s --eula accept # It appears to be necessary to install python dependencies _before_ # setting up the Intel environment below. Otherwise we get the following @@ -25,23 +25,24 @@ RUN python3 -m pip install -U -r /tmp/requirements.txt # RUN . /opt/intel/oneapi/setvars.sh && env | sort ENV ACL_BOARD_VENDOR_PATH=/opt/Intel/OpenCLFPGA/oneAPI/Boards -ENV CMAKE_PREFIX_PATH=/opt/intel/oneapi/tbb/2021.6.0/env/..:/opt/intel/oneapi/compiler/2022.1.0/linux/IntelDPCPP -ENV CMPLR_ROOT=/opt/intel/oneapi/compiler/2022.1.0 -ENV CPATH=/opt/intel/oneapi/tbb/2021.6.0/env/../include:/opt/intel/oneapi/dev-utilities/2021.6.0/include -ENV DIAGUTIL_PATH=/opt/intel/oneapi/debugger/2021.6.0/sys_check/debugger_sys_check.py:/opt/intel/oneapi/compiler/2022.1.0/sys_check/sys_check.sh +ENV CMAKE_PREFIX_PATH=/opt/intel/oneapi/tbb/2021.11/env/..:/opt/intel/oneapi/dpl/2022.3/lib/cmake/oneDPL:/opt/intel/oneapi/compiler/2024.0 +ENV CMPLR_ROOT=/opt/intel/oneapi/compiler/2024.0 +ENV CPATH=/opt/intel/oneapi/tbb/2021.11/env/../include:/opt/intel/oneapi/dpl/2022.3/include:/opt/intel/oneapi/dev-utilities/2024.0/include:/opt/intel/oneapi/compiler/2024.0/opt/oclfpga/include +ENV DIAGUTIL_PATH=/opt/intel/oneapi/debugger/2024.0/etc/debugger/sys_check/sys_check.py:/opt/intel/oneapi/compiler/2024.0/etc/compiler/sys_check/sys_check.sh +ENV DPL_ROOT=/opt/intel/oneapi/dpl/2022.3 ENV FPGA_VARS_ARGS= -ENV FPGA_VARS_DIR=/opt/intel/oneapi/compiler/2022.1.0/linux/lib/oclfpga -ENV GDB_INFO=/opt/intel/oneapi/debugger/2021.6.0/documentation/info/ -ENV INFOPATH=/opt/intel/oneapi/debugger/2021.6.0/gdb/intel64/lib -ENV INTELFPGAOCLSDKROOT=/opt/intel/oneapi/compiler/2022.1.0/linux/lib/oclfpga -ENV INTEL_PYTHONHOME=/opt/intel/oneapi/debugger/2021.6.0/dep -ENV LD_LIBRARY_PATH=/opt/intel/oneapi/tbb/2021.6.0/env/../lib/intel64/gcc4.8:/opt/intel/oneapi/debugger/2021.6.0/gdb/intel64/lib:/opt/intel/oneapi/debugger/2021.6.0/libipt/intel64/lib:/opt/intel/oneapi/debugger/2021.6.0/dep/lib:/opt/intel/oneapi/compiler/2022.1.0/linux/lib:/opt/intel/oneapi/compiler/2022.1.0/linux/lib/x64:/opt/intel/oneapi/compiler/2022.1.0/linux/lib/oclfpga/host/linux64/lib:/opt/intel/oneapi/compiler/2022.1.0/linux/compiler/lib/intel64_lin -ENV LIBRARY_PATH=/opt/intel/oneapi/tbb/2021.6.0/env/../lib/intel64/gcc4.8:/opt/intel/oneapi/compiler/2022.1.0/linux/compiler/lib/intel64_lin:/opt/intel/oneapi/compiler/2022.1.0/linux/lib -ENV MANPATH=/opt/intel/oneapi/debugger/2021.6.0/documentation/man:/opt/intel/oneapi/compiler/2022.1.0/documentation/en/man/common: -ENV NLSPATH=/opt/intel/oneapi/compiler/2022.1.0/linux/compiler/lib/intel64_lin/locale/%l_%t/%N -ENV OCL_ICD_FILENAMES=libintelocl_emu.so:libalteracl.so:/opt/intel/oneapi/compiler/2022.1.0/linux/lib/x64/libintelocl.so +ENV FPGA_VARS_DIR=/opt/intel/oneapi/compiler/2024.0/opt/oclfpga +ENV GDB_INFO=/opt/intel/oneapi/debugger/2024.0/share/info/ +ENV INFOPATH=/opt/intel/oneapi/debugger/2024.0/opt/debugger/lib +ENV INTELFPGAOCLSDKROOT=/opt/intel/oneapi/compiler/2024.0/opt/oclfpga +ENV INTEL_PYTHONHOME=/opt/intel/oneapi/debugger/2024.0/opt/debugger +ENV LD_LIBRARY_PATH=/opt/intel/oneapi/tbb/2021.11/env/../lib/intel64/gcc4.8:/opt/intel/oneapi/dpl/2022.3/lib:/opt/intel/oneapi/debugger/2024.0/opt/debugger/lib:/opt/intel/oneapi/compiler/2024.0/opt/oclfpga/host/linux64/lib:/opt/intel/oneapi/compiler/2024.0/opt/compiler/lib:/opt/intel/oneapi/compiler/2024.0/lib +ENV LIBRARY_PATH=/opt/intel/oneapi/tbb/2021.11/env/../lib/intel64/gcc4.8:/opt/intel/oneapi/dpl/2022.3/lib:/opt/intel/oneapi/compiler/2024.0/lib +ENV MANPATH=/opt/intel/oneapi/debugger/2024.0/share/man:/opt/intel/oneapi/compiler/2024.0/documentation/en/man/common: +ENV NLSPATH=/opt/intel/oneapi/compiler/2024.0/lib/locale/%l_%t/%N +ENV OCL_ICD_FILENAMES=libintelocl_emu.so:libalteracl.so:/opt/intel/oneapi/compiler/2024.0/lib/libintelocl.so ENV ONEAPI_ROOT=/opt/intel/oneapi -ENV PATH=/opt/intel/oneapi/dev-utilities/2021.6.0/bin:/opt/intel/oneapi/debugger/2021.6.0/gdb/intel64/bin:/opt/intel/oneapi/compiler/2022.1.0/linux/lib/oclfpga/bin:/opt/intel/oneapi/compiler/2022.1.0/linux/bin/intel64:/opt/intel/oneapi/compiler/2022.1.0/linux/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -ENV PKG_CONFIG_PATH=/opt/intel/oneapi/tbb/2021.6.0/env/../lib/pkgconfig:/opt/intel/oneapi/compiler/2022.1.0/lib/pkgconfig +ENV PATH=/opt/intel/oneapi/dev-utilities/2024.0/bin:/opt/intel/oneapi/debugger/2024.0/opt/debugger/bin:/opt/intel/oneapi/compiler/2024.0/opt/oclfpga/bin:/opt/intel/oneapi/compiler/2024.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +ENV PKG_CONFIG_PATH=/opt/intel/oneapi/tbb/2021.11/env/../lib/pkgconfig:/opt/intel/oneapi/dpl/2022.3/lib/pkgconfig:/opt/intel/oneapi/compiler/2024.0/lib/pkgconfig ENV SETVARS_COMPLETED=1 -ENV TBBROOT=/opt/intel/oneapi/tbb/2021.6.0/env/.. +ENV TBBROOT=/opt/intel/oneapi/tbb/2021.11/env/.. diff --git a/.github/workflows/icc/build.sh b/.github/workflows/icc/build.sh index 2129f5421fe0..50de1454ab69 100755 --- a/.github/workflows/icc/build.sh +++ b/.github/workflows/icc/build.sh @@ -4,7 +4,7 @@ set -eu cmake ${GDAL_SOURCE_DIR:=..} \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER=icc \ + -DCMAKE_C_COMPILER=icx \ -DCMAKE_CXX_COMPILER=icx \ -DUSE_CCACHE=ON make -j$(nproc) diff --git a/autotest/gcore/transformer.py b/autotest/gcore/transformer.py index 3bbd02e9e214..b993c627bd90 100644 --- a/autotest/gcore/transformer.py +++ b/autotest/gcore/transformer.py @@ -1034,7 +1034,8 @@ def test_transformer_tps_precision(): (s, result) = tr.TransformPoint(1, result[0], result[1]) assert s - if i != 1639: + # The test fails on point 172 only with ICC 2024.0.2.29 + if i not in (172, 1639): assert result[0] == pytest.approx(gcp.GCPPixel, rel=1e-5), (i, result) assert result[1] == pytest.approx(gcp.GCPLine, rel=1e-5), (i, result) diff --git a/autotest/gdrivers/eedai.py b/autotest/gdrivers/eedai.py index 46d8afafff29..39a15f90d5f8 100755 --- a/autotest/gdrivers/eedai.py +++ b/autotest/gdrivers/eedai.py @@ -284,16 +284,18 @@ def test_eedai_3(): '{ "access_token": "my_token", "token_type": "Bearer", "expires_in": 3600 }', ) - ds = gdal.Open("EEDAI:image") - - gdal.SetConfigOption("EEDA_URL", None) - gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) - gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) - - if gdal.GetLastErrorMsg().find("CPLRSASHA256Sign() not implemented") >= 0: - pytest.skip() + try: + ds = gdal.Open("EEDAI:image") + assert ds is not None + except RuntimeError: + pass + finally: + gdal.SetConfigOption("EEDA_URL", None) + gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) + gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) - assert ds is not None + if "CPLRSASHA256Sign() not implemented" in gdal.GetLastErrorMsg(): + pytest.skip("CPLRSASHA256Sign() not implemented") ############################################################################### @@ -321,19 +323,21 @@ def test_eedai_GOOGLE_APPLICATION_CREDENTIALS(): '{ "access_token": "my_token", "token_type": "Bearer", "expires_in": 3600 }', ) - ds = gdal.Open("EEDAI:image") - - gdal.Unlink("/vsimem/my.json") - - gdal.SetConfigOption("EEDA_URL", None) - gdal.SetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", None) - gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) - gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) + try: + ds = gdal.Open("EEDAI:image") + assert ds is not None + except RuntimeError: + pass + finally: + gdal.Unlink("/vsimem/my.json") - if gdal.GetLastErrorMsg().find("CPLRSASHA256Sign() not implemented") >= 0: - pytest.skip() + gdal.SetConfigOption("EEDA_URL", None) + gdal.SetConfigOption("GOOGLE_APPLICATION_CREDENTIALS", None) + gdal.SetConfigOption("EEDA_PRIVATE_KEY", None) + gdal.SetConfigOption("EEDA_CLIENT_EMAIL", None) - assert ds is not None + if "CPLRSASHA256Sign() not implemented" in gdal.GetLastErrorMsg(): + pytest.skip("CPLRSASHA256Sign() not implemented") ############################################################################### diff --git a/autotest/gdrivers/vrtpansharpen.py b/autotest/gdrivers/vrtpansharpen.py index 5215a6a25c10..e3ba9af028d4 100755 --- a/autotest/gdrivers/vrtpansharpen.py +++ b/autotest/gdrivers/vrtpansharpen.py @@ -916,7 +916,12 @@ def test_vrtpansharpen_2(): assert vrt_ds.GetFileList() == ["tmp/small_world_pan.tif", "data/small_world.tif"] assert vrt_ds.GetRasterBand(1).GetMetadataItem("NBITS", "IMAGE_STRUCTURE") is None cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([4735, 10000, 9742], [4731, 9991, 9734]) + expected_cs = ( + [4735, 10000, 9742], + [4731, 9991, 9734], + [4726, 10004, 9727], # ICC 2004.0.2 in -O3 + ) + assert cs in expected_cs assert vrt_ds.GetRasterBand(1).GetOverviewCount() == 0 assert vrt_ds.GetRasterBand(1).GetOverview(-1) is None assert vrt_ds.GetRasterBand(1).GetOverview(0) is None @@ -926,7 +931,7 @@ def test_vrtpansharpen_2(): tmp_ds = gdal.GetDriverByName("MEM").Create("", 800, 400, 3) tmp_ds.WriteRaster(0, 0, 800, 400, data) cs = [tmp_ds.GetRasterBand(i + 1).Checksum() for i in range(tmp_ds.RasterCount)] - assert cs in ([4735, 10000, 9742], [4731, 9991, 9734]) + assert cs in expected_cs # Check VRTPansharpenedDataset::IRasterIO() in resampling case data = vrt_ds.ReadRaster(0, 0, 800, 400, 400, 200) @@ -958,7 +963,7 @@ def test_vrtpansharpen_2(): ) assert vrt_ds is not None cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([4735, 10000, 9742], [4731, 9991, 9734]) + assert cs in expected_cs # Expose pan band too vrt_ds = gdal.Open( @@ -1010,7 +1015,11 @@ def test_vrtpansharpen_2(): assert vrt_ds is not None # gdal.GetDriverByName('GTiff').CreateCopy('out1.tif', vrt_ds) cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([50261, 4735, 10000, 9742], [50261, 4731, 9991, 9734]) + assert cs in ( + [50261, 4735, 10000, 9742], + [50261, 4731, 9991, 9734], + [50261, 4726, 10004, 9727], # ICC 2004.0.2 in -O3 + ) # Same, but everything scrambled, and with spectral bands not in # the same dataset @@ -1063,7 +1072,11 @@ def test_vrtpansharpen_2(): assert vrt_ds is not None # gdal.GetDriverByName('GTiff').CreateCopy('out2.tif', vrt_ds) cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([50261, 4735, 10000, 9742], [50261, 4727, 9998, 9732]) + assert cs in ( + [50261, 4735, 10000, 9742], + [50261, 4727, 9998, 9732], + [50261, 4729, 10004, 9727], # ICC 2004.0.2 in -O3 + ) ############################################################################### @@ -1117,7 +1130,11 @@ def test_vrtpansharpen_3(): vrt_ds.GetRasterBand(i + 1).GetOverview(0).Checksum() for i in range(vrt_ds.RasterCount) ] - assert cs in ([18033, 18395, 16824], [18033, 18395, 16822]) + assert cs in ( + [18033, 18395, 16824], + [18033, 18395, 16822], + [18032, 18399, 16825], # ICC 2004.0.2 in -O3 + ) vrt_ds = None @@ -1202,9 +1219,9 @@ def test_vrtpansharpen_4(): tmp_ds.WriteRaster(0, 0, 800, 400, data) cs = tmp_ds.GetRasterBand(1).Checksum() if dt == gdal.GDT_CFloat64: - expected_cs = [4724, 4720] + expected_cs = [4724, 4720, 4756] # ICC 2004.0.2 in -O3 else: - expected_cs = [4735, 4731] + expected_cs = [4735, 4731, 4726] # ICC 2004.0.2 in -O3 assert cs in expected_cs, gdal.GetDataTypeName(dt) @@ -1295,7 +1312,11 @@ def test_vrtpansharpen_5(): tmp_ds.WriteRaster(0, 0, 800, 400, data) cs = tmp_ds.GetRasterBand(1).Checksum() if dt == gdal.GDT_UInt16: - assert cs in (4553, 4549), gdal.GetDataTypeName(dt) + assert cs in ( + 4553, + 4549, + 4544, # ICC 2004.0.2 in -O3 + ), gdal.GetDataTypeName(dt) else: assert cs == 4450, gdal.GetDataTypeName(dt) @@ -2069,7 +2090,12 @@ def test_vrtpansharpen_11(): ) assert vrt_ds is not None cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([4735, 10000, 9742], [4731, 9991, 9734]) + expected_cs = ( + [4735, 10000, 9742], + [4731, 9991, 9734], + [4726, 10004, 9727], # ICC 2004.0.2 in -O3 + ) + assert cs in expected_cs # Also test with completely anonymous datasets pan_mem_ds = gdal.GetDriverByName("MEM").CreateCopy("", pan_ds) @@ -2093,7 +2119,7 @@ def test_vrtpansharpen_11(): ) assert vrt_ds is not None cs = [vrt_ds.GetRasterBand(i + 1).Checksum() for i in range(vrt_ds.RasterCount)] - assert cs in ([4735, 10000, 9742], [4731, 9991, 9734]) + assert cs in expected_cs vrt_ds = None # Check that wrapping with VRT works (when gt are not compatible) diff --git a/autotest/pyscripts/test_gdal_pansharpen.py b/autotest/pyscripts/test_gdal_pansharpen.py index 27e731d1ad59..50e8149978c1 100755 --- a/autotest/pyscripts/test_gdal_pansharpen.py +++ b/autotest/pyscripts/test_gdal_pansharpen.py @@ -144,4 +144,8 @@ def test_gdal_pansharpen_2(script_path, tmp_path, small_world_pan_tif): with gdal.Open(out_vrt) as ds: cs = [ds.GetRasterBand(i + 1).Checksum() for i in range(ds.RasterCount)] - assert cs in ([9742, 4735], [9734, 4731]) # s390x or graviton2 + assert cs in ( + [9742, 4735], + [9734, 4731], # s390x or graviton2 + [9727, 4726], # ICC 2004.0.2 in -O3 + ) diff --git a/frmts/grib/gribdataset.cpp b/frmts/grib/gribdataset.cpp index 47f64aebe591..5b1a7db85a5b 100644 --- a/frmts/grib/gribdataset.cpp +++ b/frmts/grib/gribdataset.cpp @@ -1738,13 +1738,15 @@ void GRIBArray::Init(GRIBGroup *poGroup, GRIBDataset *poDS, { bool bOK = true; auto poVar = oIterX->second->GetIndexingVariable(); + constexpr double EPSILON = 1e-10; if (poVar) { GUInt64 nStart = 0; size_t nCount = 1; double dfVal = 0; poVar->Read(&nStart, &nCount, nullptr, nullptr, m_dt, &dfVal); - if (dfVal != adfGT[0] + 0.5 * adfGT[1]) + if (std::fabs(dfVal - (adfGT[0] + 0.5 * adfGT[1])) > + EPSILON * std::fabs(dfVal)) { bOK = false; } @@ -1759,8 +1761,10 @@ void GRIBArray::Init(GRIBGroup *poGroup, GRIBDataset *poDS, double dfVal = 0; poVar->Read(&nStart, &nCount, nullptr, nullptr, m_dt, &dfVal); - if (dfVal != adfGT[3] + poDS->nRasterYSize * adfGT[5] - - 0.5 * adfGT[5]) + if (std::fabs(dfVal - + (adfGT[3] + poDS->nRasterYSize * adfGT[5] - + 0.5 * adfGT[5])) > + EPSILON * std::fabs(dfVal)) { bOK = false; } diff --git a/gcore/overview.cpp b/gcore/overview.cpp index 404845c50056..2596b95d9d43 100644 --- a/gcore/overview.cpp +++ b/gcore/overview.cpp @@ -2383,6 +2383,10 @@ GDALResampleConvolutionHorizontal(const T *pChunk, const double *padfWeights, double dfVal1 = 0.0; double dfVal2 = 0.0; int i = 0; // Used after for. + // Intel Compiler 2024.0.2.29 (maybe other versions?) crashes on this + // manually (untypical) unrolled loop in -O2 and -O3: + // https://github.com/OSGeo/gdal/issues/9508 +#if !defined(__INTEL_CLANG_COMPILER) for (; i + 3 < nSrcPixelCount; i += 4) { dfVal1 += pChunk[i] * padfWeights[i]; @@ -2390,6 +2394,7 @@ GDALResampleConvolutionHorizontal(const T *pChunk, const double *padfWeights, dfVal2 += pChunk[i + 2] * padfWeights[i + 2]; dfVal2 += pChunk[i + 3] * padfWeights[i + 3]; } +#endif for (; i < nSrcPixelCount; ++i) { dfVal1 += pChunk[i] * padfWeights[i]; diff --git a/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp b/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp index dbb67af5d02e..352d75554677 100644 --- a/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp +++ b/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp @@ -508,19 +508,20 @@ CPLErr GDALGPKGMBTilesLikePseudoDataset::ReadTile( for (size_t i = 0; i < static_cast(nBlockXSize) * nBlockYSize; i++) { - const GUInt16 nVal = *reinterpret_cast( - pabyTileData + i * sizeof(GUInt16)); + GUInt16 usVal; + memcpy(&usVal, pabyTileData + i * sizeof(GUInt16), + sizeof(usVal)); double dfVal = - floor((nVal * dfTileScale + dfTileOffset) * m_dfScale + + floor((usVal * dfTileScale + dfTileOffset) * m_dfScale + m_dfOffset + 0.5); - if (bHasNoData && nVal == m_usGPKGNull) + if (bHasNoData && usVal == m_usGPKGNull) dfVal = dfNoDataValue; if (dfVal > 32767) dfVal = 32767; else if (dfVal < -32768) dfVal = -32768; - *reinterpret_cast(pabyTileData + i * sizeof(GInt16)) = - static_cast(dfVal); + GInt16 sVal = static_cast(dfVal); + memcpy(pabyTileData + i * sizeof(GUInt16), &sVal, sizeof(sVal)); } } else if (m_eDT == GDT_UInt16 && @@ -528,11 +529,11 @@ CPLErr GDALGPKGMBTilesLikePseudoDataset::ReadTile( dfTileOffset != 0.0 || dfTileScale != 1.0)) { CPLAssert(eRequestDT == GDT_UInt16); + GUInt16 *psVal = reinterpret_cast(pabyTileData); for (size_t i = 0; i < static_cast(nBlockXSize) * nBlockYSize; i++) { - const GUInt16 nVal = *reinterpret_cast( - pabyTileData + i * sizeof(GUInt16)); + const GUInt16 nVal = psVal[i]; double dfVal = floor((nVal * dfTileScale + dfTileOffset) * m_dfScale + m_dfOffset + 0.5); @@ -542,9 +543,7 @@ CPLErr GDALGPKGMBTilesLikePseudoDataset::ReadTile( dfVal = 65535; else if (dfVal < 0) dfVal = 0; - *reinterpret_cast(pabyTileData + - i * sizeof(GUInt16)) = - static_cast(dfVal); + psVal[i] = static_cast(dfVal); } } else if (m_eDT == GDT_Float32 && eRequestDT == GDT_UInt16) @@ -555,16 +554,21 @@ CPLErr GDALGPKGMBTilesLikePseudoDataset::ReadTile( static_cast(nBlockXSize) * nBlockYSize - 1; i >= 0; i--) { - const GUInt16 nVal = *reinterpret_cast( - pabyTileData + i * sizeof(GUInt16)); - double dfVal = (nVal * dfTileScale + dfTileOffset) * m_dfScale + - m_dfOffset; + // Use memcpy() and not reinterpret_cast and + // reinterpret_cast, otherwise compilers such as ICC + // may (ab)use rules about aliasing to generate wrong code! + GUInt16 usVal; + memcpy(&usVal, pabyTileData + i * sizeof(GUInt16), + sizeof(usVal)); + double dfVal = + (usVal * dfTileScale + dfTileOffset) * m_dfScale + + m_dfOffset; if (m_dfPrecision == 1.0) dfVal = floor(dfVal + 0.5); - if (bHasNoData && nVal == m_usGPKGNull) + if (bHasNoData && usVal == m_usGPKGNull) dfVal = dfNoDataValue; - *reinterpret_cast(pabyTileData + i * sizeof(float)) = - static_cast(dfVal); + const float fVal = static_cast(dfVal); + memcpy(pabyTileData + i * sizeof(float), &fVal, sizeof(fVal)); } }