|
From: Scott Z. <Sco...@ro...> - 2012-10-29 19:50:11
|
Hi,
There is an optimization bug with the MSVC 11 32-bit compiler that caused ISO_2022_JP, ISO_2022_JP_1, ISO_2022_JP_2, HZ and JIS character encoding conversion test to fail (see https://connect.microsoft.com/VisualStudio/feedback/details/768624/broken-optimization-in-string-processing#tabs). The cintltst for ICU 4.4.2 results are:
SUMMARY:
******* [Total error count: 590]
Errors in
[/tsconv/nucnvtst/TestISO_2022_JP]
[/tsconv/nucnvtst/TestJIS]
[/tsconv/nucnvtst/TestISO_2022_JP_1]
[/tsconv/nucnvtst/TestISO_2022_JP_2]
[/tsconv/nucnvtst/TestHZ]
[/tsconv/nucnvtst/TestJitterbug2346]
[/tsconv/nccbtst/TestSkipCallBack]
[/tsconv/nccbtst/TestSubWithValueCallBack]
[/tsconv/ncnvtst/TestResetBehaviour]
I had also tried ICU 49.1.2 and ICU 50 with the same result, this seem to indicate that both of those are also affected. I made the following modification to work around this optimization bug.
--- ucnvhz.c.orig 2010-09-29 11:37:20.000000000 -0700
+++ ucnvhz.c 2012-10-29 11:36:03.520615200 -0700
@@ -52,6 +52,21 @@
} \
}
+/**
+ * Workaround MSVC 2011 32-bit optimization bug
+ */
+#ifdef U_HAVE_MSVC_2011_32_BIT
+#pragma optimize( "", off)
+#endif
+
+static UBool U_maybe_noinline_AND(const uint8_t x, const uint8_t y)
+{
+ return (x && y) ? TRUE : FALSE;
+}
+
+#ifdef U_HAVE_MSVC_2011_32_BIT
+#pragma optimize( "", on)
+#endif
typedef struct{
UConverter* gbConverter;
@@ -263,7 +278,7 @@
*/
leadIsOk = (uint8_t)(leadByte - 0x21) <= (0x7d - 0x21);
trailIsOk = (uint8_t)(mySourceChar - 0x21) <= (0x7e - 0x21);
- if (leadIsOk && trailIsOk) {
+ if (U_maybe_noinline_AND(leadIsOk, trailIsOk)) {
tempBuf[0] = (char) (leadByte+0x80) ;
tempBuf[1] = (char) (mySourceChar+0x80);
targetUniChar = ucnv_MBCSSimpleGetNextUChar(myData->gbConverter->sharedData,
--- ucnv2022.c.orig 2010-09-29 11:37:20.000000000 -0700
+++ ucnv2022.c 2012-10-29 11:35:17.052323400 -0700
@@ -43,6 +43,22 @@
#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+/**
+ * Workaround MSVC 2011 32-bit optimization bug
+ */
+#ifdef U_HAVE_MSVC_2011_32_BIT
+#pragma optimize( "", off)
+#endif
+
+static UBool U_maybe_noinline_AND(const uint8_t x, const uint8_t y)
+{
+ return (x && y) ? TRUE : FALSE;
+}
+
+#ifdef U_HAVE_MSVC_2011_32_BIT
+#pragma optimize( "", on)
+#endif
+
#ifdef U_ENABLE_GENERIC_ISO_2022
/*
* I am disabling the generic ISO-2022 converter after proposing to do so on
@@ -2188,7 +2204,7 @@
*/
leadIsOk = (uint8_t)(mySourceChar - 0x21) <= (0x7e - 0x21);
trailIsOk = (uint8_t)(trailByte - 0x21) <= (0x7e - 0x21);
- if (leadIsOk && trailIsOk) {
+ if (U_maybe_noinline_AND(leadIsOk, trailIsOk)) {
++mySource;
tmpSourceChar = (mySourceChar << 8) | trailByte;
if(cs == JISX208) {
@@ -2702,7 +2718,7 @@
*/
leadIsOk = (uint8_t)(mySourceChar - 0x21) <= (0x7e - 0x21);
trailIsOk = (uint8_t)(trailByte - 0x21) <= (0x7e - 0x21);
- if (leadIsOk && trailIsOk) {
+ if (U_maybe_noinline_AND(leadIsOk, trailIsOk)) {
++mySource;
tempBuf[0] = (char)(mySourceChar + 0x80);
tempBuf[1] = (char)(trailByte + 0x80);
@@ -3316,7 +3332,7 @@
*/
leadIsOk = (uint8_t)(mySourceChar - 0x21) <= (0x7e - 0x21);
trailIsOk = (uint8_t)(trailByte - 0x21) <= (0x7e - 0x21);
- if (leadIsOk && trailIsOk) {
+ if (U_maybe_noinline_AND(leadIsOk, trailIsOk)) {
++mySource;
tempState = (StateEnum)pToU2022State->cs[pToU2022State->g];
if(tempState >= CNS_11643_0) {
--- unicode/pwin32.h.orig 2010-09-29 11:37:16.000000000 -0700
+++ unicode/pwin32.h 2012-10-29 11:33:00.730064400 -0700
@@ -356,6 +356,12 @@
#define U_HAVE_MSVC_2003_OR_EARLIER
#endif
+/**
+ * Flag for workaround of MSVC 2011 32-bit optimization bug
+ */
+#if defined(_MSC_VER) && (_MSC_VER == 1700) && !defined(_WIN64)
+#define U_HAVE_MSVC_2011_32_BIT
+#endif
/** @} */
Regards,
Scott
|