aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/opts/SkBitmapProcState_opts_SSE2.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/opts/SkBitmapProcState_opts_SSE2.cpp b/src/opts/SkBitmapProcState_opts_SSE2.cpp
index 9ddf269ec9..efe8f4dd2e 100644
--- a/src/opts/SkBitmapProcState_opts_SSE2.cpp
+++ b/src/opts/SkBitmapProcState_opts_SSE2.cpp
@@ -361,10 +361,31 @@ void ClampX_ClampY_filter_scale_SSE2(const SkBitmapProcState& s, uint32_t xy[],
} // while count >= 4
} // if count >= 4
+ /*
while (count-- > 0) {
*xy++ = ClampX_ClampY_pack_filter(fx, maxX, one);
fx += dx;
}
+ We'd like to write this as above, but that form allows fx to get 1-iteration too big/small
+ when count is 0, and this can trigger a UBSAN error, even though we won't in fact use that
+ last (undefined) value for fx.
+
+ Here is an alternative that should always be efficient, but seems much harder to read:
+
+ if (count > 0) {
+ for (;;) {
+ *xy++ = ClampX_ClampY_pack_filter(fx, maxX, one);
+ if (--count == 0) break;
+ fx += dx;
+ }
+ }
+
+ For now, we'll try this variant: more compact than the if/for version, and we hope the
+ compiler will get rid of the integer multiply.
+ */
+ for (int i = 0; i < count; ++i) {
+ *xy++ = ClampX_ClampY_pack_filter(fx + i*dx, maxX, one);
+ }
}
}