[x265] [PATCH 5 of 5] avoid left-shifts on signed integers and undefined behavior traps

Steve Borho steve at borho.org
Wed Feb 25 20:42:27 CET 2015


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1424891654 21600
#      Wed Feb 25 13:14:14 2015 -0600
# Node ID 594c4e38c4bbdef6cea6cc1c2547bd4162a0be96
# Parent  7b0018aeae9ae6facb870666107efc58896f25fd
avoid left-shifts on signed integers and undefined behavior traps

diff -r 7b0018aeae9a -r 594c4e38c4bb source/common/bitstream.cpp
--- a/source/common/bitstream.cpp	Wed Feb 25 12:16:28 2015 -0600
+++ b/source/common/bitstream.cpp	Wed Feb 25 13:14:14 2015 -0600
@@ -44,7 +44,7 @@
 void Bitstream::write(uint32_t val, uint32_t numBits)
 {
     X265_CHECK(numBits <= 32, "numBits out of range\n");
-    X265_CHECK(numBits == 32 || ((val & (~0 << numBits)) == 0), "numBits & val out of range\n");
+    X265_CHECK(numBits == 32 || ((val & (~0u << numBits)) == 0), "numBits & val out of range\n");
 
     uint32_t totalPartialBits = m_partialByteBits + numBits;
     uint32_t nextPartialBits = totalPartialBits & 7;
diff -r 7b0018aeae9a -r 594c4e38c4bb source/common/cudata.cpp
--- a/source/common/cudata.cpp	Wed Feb 25 12:16:28 2015 -0600
+++ b/source/common/cudata.cpp	Wed Feb 25 13:14:14 2015 -0600
@@ -1766,16 +1766,17 @@
 
 void CUData::clipMv(MV& outMV) const
 {
-    int mvshift = 2;
-    int offset = 8;
-    int xmax = (m_slice->m_sps->picWidthInLumaSamples + offset - m_cuPelX - 1) << mvshift;
-    int xmin = (-(int)g_maxCUSize - offset - (int)m_cuPelX + 1) << mvshift;
+    const uint32_t mvshift = 2;
+    uint32_t offset = 8;
 
-    int ymax = (m_slice->m_sps->picHeightInLumaSamples + offset - m_cuPelY - 1) << mvshift;
-    int ymin = (-(int)g_maxCUSize - offset - (int)m_cuPelY + 1) << mvshift;
+    int16_t xmax = (int16_t)((m_slice->m_sps->picWidthInLumaSamples + offset - m_cuPelX - 1) << mvshift);
+    int16_t xmin = -(int16_t)((g_maxCUSize + offset + m_cuPelX - 1) << mvshift);
 
-    outMV.x = (int16_t)X265_MIN(xmax, X265_MAX(xmin, (int)outMV.x));
-    outMV.y = (int16_t)X265_MIN(ymax, X265_MAX(ymin, (int)outMV.y));
+    int16_t ymax = (int16_t)((m_slice->m_sps->picHeightInLumaSamples + offset - m_cuPelY - 1) << mvshift);
+    int16_t ymin = -(int16_t)((g_maxCUSize + offset + m_cuPelY - 1) << mvshift);
+
+    outMV.x = X265_MIN(xmax, X265_MAX(xmin, outMV.x));
+    outMV.y = X265_MIN(ymax, X265_MAX(ymin, outMV.y));
 }
 
 bool CUData::addMVPCand(MV& mvp, int picList, int refIdx, uint32_t partUnitIdx, MVP_DIR dir) const
diff -r 7b0018aeae9a -r 594c4e38c4bb source/common/deblock.cpp
--- a/source/common/deblock.cpp	Wed Feb 25 12:16:28 2015 -0600
+++ b/source/common/deblock.cpp	Wed Feb 25 13:14:14 2015 -0600
@@ -358,7 +358,7 @@
         int16_t m5  = (int16_t)src[offset];
         int16_t m2  = (int16_t)src[-offset * 2];
 
-        int32_t delta = x265_clip3(-tc, tc, ((((m4 - m3) << 2) + m2 - m5 + 4) >> 3));
+        int32_t delta = x265_clip3(-tc, tc, ((((m4 - m3) * 4) + m2 - m5 + 4) >> 3));
         src[-offset] = x265_clip(m3 + (delta & maskP));
         src[0] = x265_clip(m4 - (delta & maskQ));
     }
diff -r 7b0018aeae9a -r 594c4e38c4bb source/common/mv.h
--- a/source/common/mv.h	Wed Feb 25 12:16:28 2015 -0600
+++ b/source/common/mv.h	Wed Feb 25 13:14:14 2015 -0600
@@ -56,12 +56,17 @@
 
     MV& operator >>=(int i)                    { x >>= i; y >>= i; return *this; }
 
+#if CHECKED_BUILD
+    /* avoid signed left-shifts when -ftrapv is enabled */
+    MV& operator <<=(int i)                    { x *= (1 << i); y *= (1 << i); return *this; }
+    MV operator <<(int i) const                { return MV(x * (1 << i), y * (1 << i)); }
+#else
     MV& operator <<=(int i)                    { x <<= i; y <<= i; return *this; }
+    MV operator <<(int i) const                { return MV(x << i, y << i); }
+#endif
 
     MV operator >>(int i) const                { return MV(x >> i, y >> i); }
 
-    MV operator <<(int i) const                { return MV(x << i, y << i); }
-
     MV operator *(int16_t i) const             { return MV(x * i, y * i); }
 
     MV operator -(const MV& other) const       { return MV(x - other.x, y - other.y); }
diff -r 7b0018aeae9a -r 594c4e38c4bb source/encoder/weightPrediction.cpp
--- a/source/encoder/weightPrediction.cpp	Wed Feb 25 12:16:28 2015 -0600
+++ b/source/encoder/weightPrediction.cpp	Wed Feb 25 13:14:14 2015 -0600
@@ -58,6 +58,7 @@
 void mcLuma(pixel* mcout, Lowres& ref, const MV * mvs)
 {
     intptr_t stride = ref.lumaStride;
+    const int mvshift = 1 << 2;
     const int cuSize = 8;
     MV mvmin, mvmax;
 
@@ -66,15 +67,15 @@
     for (int y = 0; y < ref.lines; y += cuSize)
     {
         intptr_t pixoff = y * stride;
-        mvmin.y = (int16_t)((-y - 8) << 2);
-        mvmax.y = (int16_t)((ref.lines - y - 1 + 8) << 2);
+        mvmin.y = (int16_t)((-y - 8) * mvshift);
+        mvmax.y = (int16_t)((ref.lines - y - 1 + 8) * mvshift);
 
         for (int x = 0; x < ref.width; x += cuSize, pixoff += cuSize, cu++)
         {
             ALIGN_VAR_16(pixel, buf8x8[8 * 8]);
             intptr_t bstride = 8;
-            mvmin.x = (int16_t)((-x - 8) << 2);
-            mvmax.x = (int16_t)((ref.width - x - 1 + 8) << 2);
+            mvmin.x = (int16_t)((-x - 8) * mvshift);
+            mvmax.x = (int16_t)((ref.width - x - 1 + 8) * mvshift);
 
             /* clip MV to available pixels */
             MV mv = mvs[cu];
@@ -100,6 +101,7 @@
     int csp = cache.csp;
     int bw = 16 >> cache.hshift;
     int bh = 16 >> cache.vshift;
+    const int mvshift = 1 << 2;
     MV mvmin, mvmax;
 
     for (int y = 0; y < height; y += bh)
@@ -109,8 +111,8 @@
          * into the lowres structures */
         int cu = y * cache.lowresWidthInCU;
         intptr_t pixoff = y * stride;
-        mvmin.y = (int16_t)((-y - 8) << 2);
-        mvmax.y = (int16_t)((height - y - 1 + 8) << 2);
+        mvmin.y = (int16_t)((-y - 8) * mvshift);
+        mvmax.y = (int16_t)((height - y - 1 + 8) * mvshift);
 
         for (int x = 0; x < width; x += bw, cu++, pixoff += bw)
         {
@@ -122,8 +124,8 @@
                 mv.y >>= cache.vshift;
 
                 /* clip MV to available pixels */
-                mvmin.x = (int16_t)((-x - 8) << 2);
-                mvmax.x = (int16_t)((width - x - 1 + 8) << 2);
+                mvmin.x = (int16_t)((-x - 8) * mvshift);
+                mvmax.x = (int16_t)((width - x - 1 + 8) * mvshift);
                 mv = mv.clipped(mvmin, mvmax);
 
                 intptr_t fpeloffset = (mv.y >> 2) * stride + (mv.x >> 2);


More information about the x265-devel mailing list