Fix for Issue #3164.
authorLubomir Litchev <lubol@microsoft.com>
Thu, 17 Sep 2015 05:53:49 +0000 (22:53 -0700)
committerLubomir Litchev <lubol@microsoft.com>
Thu, 17 Sep 2015 05:53:49 +0000 (22:53 -0700)
Added extra code to work around an optimizer bug in clang 3.5. In a
particular case 0/MIN_LONG results into MIN_LONG that causes a const
folding to produce a result of 0 instead of overflow exception for
MIN_LONG * MIN_LONG.

src/jit/gentree.cpp

index fafe416..861240b 100644 (file)
@@ -10166,6 +10166,18 @@ LNG_ADD_CHKOVF:
                             goto LNG_OVF;
                         }
                         if ((ltemp/lval2) != lval1) goto LNG_OVF;
+#ifdef UNIX_AMD64_ABI
+                        // There is a clang 3.5 optimizer bug that in case of lval1 and lval2 equal
+                        // of 0x80000000 (MIN_LONG) the above expression (ltemp / lval2) results
+                        // in 0x80000000 (MIN_LONG. This causes an overflowing mul expression 
+                        // to be repalced with a 0, instead of throwing an overflow exception.
+                        // The following extra check fixes the issue. If the bug is fixed in later releases 
+                        // of clang this fix becomes dead code since the goto above will trigger.
+                        // In debug builds the expression result is correct - 0.
+                        // The lval1 and lval2 are checked to be non-zeroes above.
+                        // If multiplication of 2 non-zeroes results in a zero results, it must be an overflow.
+                        if (ltemp == 0) goto LNG_OVF;
+#endif // UNIX_AMD64_ABI
                     }
                 }
             }