diff options
author | Lubomir Litchev <lubol@microsoft.com> | 2015-09-18 10:58:12 -0700 |
---|---|---|
committer | Lubomir Litchev <lubol@microsoft.com> | 2015-09-18 11:05:32 -0700 |
commit | 93a90d45e66eefe916295f2812a3c6437b0806b3 (patch) | |
tree | ad8c5fc3c1c4367fbe9bdb313659715e90a4ed2d /src/jit | |
parent | 8ff8514192ff83a1625f009bb5783a3ee675e072 (diff) | |
download | coreclr-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.h | 12 | ||||
-rw-r--r-- | src/jit/gentree.cpp | 22 |
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 } } } |