summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorLubomir Litchev <lubol@microsoft.com>2015-09-18 10:58:12 -0700
committerLubomir Litchev <lubol@microsoft.com>2015-09-18 11:05:32 -0700
commit93a90d45e66eefe916295f2812a3c6437b0806b3 (patch)
treead8c5fc3c1c4367fbe9bdb313659715e90a4ed2d /src/jit
parent8ff8514192ff83a1625f009bb5783a3ee675e072 (diff)
downloadcoreclr-93a90d45e66eefe916295f2812a3c6437b0806b3.tar.gz
coreclr-93a90d45e66eefe916295f2812a3c6437b0806b3.tar.bz2
coreclr-93a90d45e66eefe916295f2812a3c6437b0806b3.zip
Disable the clang/llvm optimizer for a method that triggers wrong codegen.
There is a bug in the clang-3.5 optimizer. The issue is that in release build the optimizer is mistyping (or just wrongly decides to use 32 bit operation for a corner case of MIN_LONG) the args of the (ltemp / lval2) to int (it does a 32 bit div operation instead of 64 bit.) For the case of lval1 and lval2 equal to MIN_LONG (0x8000000000000000) this results in raising a SIGFPE.
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/compiler.h12
-rw-r--r--src/jit/gentree.cpp22
2 files changed, 21 insertions, 13 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index c6063dae20..520c94a462 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -1971,7 +1971,17 @@ public:
//-------------------------------------------------------------------------
GenTreePtr gtFoldExpr (GenTreePtr tree);
- GenTreePtr gtFoldExprConst (GenTreePtr tree);
+ GenTreePtr
+#ifdef __clang__
+ // TODO-Amd64-Unix: Remove this when the clang optimizer is fixed and/or the method implementation is refactored in a simpler code.
+ // This is a workaround for a bug in the clang-3.5 optimizer. The issue is that in release build the optimizer is mistyping
+ // (or just wrongly decides to use 32 bit operation for a corner case of MIN_LONG) the args of the (ltemp / lval2)
+ // to int (it does a 32 bit div operation instead of 64 bit) - see the implementation of the method in gentree.cpp.
+ // For the case of lval1 and lval2 equal to MIN_LONG (0x8000000000000000) this results in raising a SIGFPE.
+ // The method implementation is rather complex. Disable optimizations for now.
+ __attribute__((optnone))
+#endif // __clang__
+ gtFoldExprConst(GenTreePtr tree);
GenTreePtr gtFoldExprSpecial(GenTreePtr tree);
GenTreePtr gtFoldExprCompare(GenTreePtr tree);
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 861240b8c9..284000e55b 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -10141,8 +10141,10 @@ LNG_ADD_CHKOVF:
case GT_MUL:
ltemp = lval1 * lval2;
+
if (tree->gtOverflow() && lval2 != 0)
{
+
if (tree->gtFlags & GTF_UNSIGNED)
{
UINT64 ultemp = ltemp;
@@ -10165,19 +10167,15 @@ LNG_ADD_CHKOVF:
{
goto LNG_OVF;
}
+
+ // TODO-Amd64-Unix: Remove the code that disables optimizations for this method when the clang
+ // optimizer is fixed and/or the method implementation is refactored in a simpler code.
+ // There is a bug in the clang-3.5 optimizer. The issue is that in release build the optimizer is mistyping
+ // (or just wrongly decides to use 32 bit operation for a corner case of MIN_LONG) the args of the (ltemp / lval2)
+ // to int (it does a 32 bit div operation instead of 64 bit.)
+ // For the case of lval1 and lval2 equal to MIN_LONG (0x8000000000000000) this results in raising a SIGFPE.
+ // Optimizations disabled for now. See compiler.h.
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
}
}
}