Fix for rhbz#1657544
This commit is contained in:
parent
1e5a2ecac9
commit
1f58b21528
122
0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch
Normal file
122
0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
From b9d6dba608ab50d2e4a1b0f2318a5d1b390fc702 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vedant Kumar <vsk@apple.com>
|
||||||
|
Date: Tue, 18 Dec 2018 21:05:03 +0000
|
||||||
|
Subject: [PATCH] [CodeGen] Handle mixed-width ops in mixed-sign
|
||||||
|
mul-with-overflow lowering
|
||||||
|
|
||||||
|
The special lowering for __builtin_mul_overflow introduced in r320902
|
||||||
|
fixed an ICE seen when passing mixed-sign operands to the builtin.
|
||||||
|
|
||||||
|
This patch extends the special lowering to cover mixed-width, mixed-sign
|
||||||
|
operands. In a few common scenarios, calls to muloti4 will no longer be
|
||||||
|
emitted.
|
||||||
|
|
||||||
|
This should address the latest comments in PR34920 and work around the
|
||||||
|
link failure seen in:
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1657544
|
||||||
|
|
||||||
|
Testing:
|
||||||
|
- check-clang
|
||||||
|
- A/B output comparison with: https://gist.github.com/vedantk/3eb9c88f82e5c32f2e590555b4af5081
|
||||||
|
|
||||||
|
Differential Revision: https://reviews.llvm.org/D55843
|
||||||
|
|
||||||
|
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349542 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||||
|
---
|
||||||
|
lib/CodeGen/CGBuiltin.cpp | 19 ++++++++++++++-----
|
||||||
|
test/CodeGen/builtins-overflow.c | 21 +++++++++++++++++++++
|
||||||
|
2 files changed, 35 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
|
||||||
|
index 0770c20..4303a7a 100644
|
||||||
|
--- a/lib/CodeGen/CGBuiltin.cpp
|
||||||
|
+++ b/lib/CodeGen/CGBuiltin.cpp
|
||||||
|
@@ -1077,7 +1077,7 @@ static bool isSpecialMixedSignMultiply(unsigned BuiltinID,
|
||||||
|
WidthAndSignedness Op2Info,
|
||||||
|
WidthAndSignedness ResultInfo) {
|
||||||
|
return BuiltinID == Builtin::BI__builtin_mul_overflow &&
|
||||||
|
- Op1Info.Width == Op2Info.Width && Op1Info.Width >= ResultInfo.Width &&
|
||||||
|
+ std::max(Op1Info.Width, Op2Info.Width) >= ResultInfo.Width &&
|
||||||
|
Op1Info.Signed != Op2Info.Signed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1098,11 +1098,20 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
|
||||||
|
const clang::Expr *UnsignedOp = Op1Info.Signed ? Op2 : Op1;
|
||||||
|
llvm::Value *Signed = CGF.EmitScalarExpr(SignedOp);
|
||||||
|
llvm::Value *Unsigned = CGF.EmitScalarExpr(UnsignedOp);
|
||||||
|
+ unsigned SignedOpWidth = Op1Info.Signed ? Op1Info.Width : Op2Info.Width;
|
||||||
|
+ unsigned UnsignedOpWidth = Op1Info.Signed ? Op2Info.Width : Op1Info.Width;
|
||||||
|
+
|
||||||
|
+ // One of the operands may be smaller than the other. If so, [s|z]ext it.
|
||||||
|
+ if (SignedOpWidth < UnsignedOpWidth)
|
||||||
|
+ Signed = CGF.Builder.CreateSExt(Signed, Unsigned->getType(), "op.sext");
|
||||||
|
+ if (UnsignedOpWidth < SignedOpWidth)
|
||||||
|
+ Unsigned = CGF.Builder.CreateZExt(Unsigned, Signed->getType(), "op.zext");
|
||||||
|
|
||||||
|
llvm::Type *OpTy = Signed->getType();
|
||||||
|
llvm::Value *Zero = llvm::Constant::getNullValue(OpTy);
|
||||||
|
Address ResultPtr = CGF.EmitPointerWithAlignment(ResultArg);
|
||||||
|
llvm::Type *ResTy = ResultPtr.getElementType();
|
||||||
|
+ unsigned OpWidth = std::max(Op1Info.Width, Op2Info.Width);
|
||||||
|
|
||||||
|
// Take the absolute value of the signed operand.
|
||||||
|
llvm::Value *IsNegative = CGF.Builder.CreateICmpSLT(Signed, Zero);
|
||||||
|
@@ -1120,8 +1129,8 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
|
||||||
|
if (ResultInfo.Signed) {
|
||||||
|
// Signed overflow occurs if the result is greater than INT_MAX or lesser
|
||||||
|
// than INT_MIN, i.e when |Result| > (INT_MAX + IsNegative).
|
||||||
|
- auto IntMax = llvm::APInt::getSignedMaxValue(ResultInfo.Width)
|
||||||
|
- .zextOrSelf(Op1Info.Width);
|
||||||
|
+ auto IntMax =
|
||||||
|
+ llvm::APInt::getSignedMaxValue(ResultInfo.Width).zextOrSelf(OpWidth);
|
||||||
|
llvm::Value *MaxResult =
|
||||||
|
CGF.Builder.CreateAdd(llvm::ConstantInt::get(OpTy, IntMax),
|
||||||
|
CGF.Builder.CreateZExt(IsNegative, OpTy));
|
||||||
|
@@ -1139,9 +1148,9 @@ EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
|
||||||
|
llvm::Value *Underflow = CGF.Builder.CreateAnd(
|
||||||
|
IsNegative, CGF.Builder.CreateIsNotNull(UnsignedResult));
|
||||||
|
Overflow = CGF.Builder.CreateOr(UnsignedOverflow, Underflow);
|
||||||
|
- if (ResultInfo.Width < Op1Info.Width) {
|
||||||
|
+ if (ResultInfo.Width < OpWidth) {
|
||||||
|
auto IntMax =
|
||||||
|
- llvm::APInt::getMaxValue(ResultInfo.Width).zext(Op1Info.Width);
|
||||||
|
+ llvm::APInt::getMaxValue(ResultInfo.Width).zext(OpWidth);
|
||||||
|
llvm::Value *TruncOverflow = CGF.Builder.CreateICmpUGT(
|
||||||
|
UnsignedResult, llvm::ConstantInt::get(OpTy, IntMax));
|
||||||
|
Overflow = CGF.Builder.CreateOr(Overflow, TruncOverflow);
|
||||||
|
diff --git a/test/CodeGen/builtins-overflow.c b/test/CodeGen/builtins-overflow.c
|
||||||
|
index 57f90eb..79a3186 100644
|
||||||
|
--- a/test/CodeGen/builtins-overflow.c
|
||||||
|
+++ b/test/CodeGen/builtins-overflow.c
|
||||||
|
@@ -339,6 +339,27 @@ long long test_smulll_overflow(long long x, long long y) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int test_mixed_sign_mul_overflow_sext_signed_op(int x, unsigned long long y) {
|
||||||
|
+// CHECK: @test_mixed_sign_mul_overflow_sext_signed_op
|
||||||
|
+// CHECK: [[SignedOp:%.*]] = sext i32 %0 to i64
|
||||||
|
+// CHECK: [[IsNeg:%.*]] = icmp slt i64 [[SignedOp]], 0
|
||||||
|
+ int result;
|
||||||
|
+ if (__builtin_mul_overflow(x, y, &result))
|
||||||
|
+ return LongErrorCode;
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int test_mixed_sign_mul_overflow_zext_unsigned_op(long long x, unsigned y) {
|
||||||
|
+// CHECK: @test_mixed_sign_mul_overflow_zext_unsigned_op
|
||||||
|
+// CHECK: [[UnsignedOp:%.*]] = zext i32 %1 to i64
|
||||||
|
+// CHECK: [[IsNeg:%.*]] = icmp slt i64 %0, 0
|
||||||
|
+// CHECK: @llvm.umul.with.overflow.i64({{.*}}, i64 [[UnsignedOp]])
|
||||||
|
+ int result;
|
||||||
|
+ if (__builtin_mul_overflow(x, y, &result))
|
||||||
|
+ return LongErrorCode;
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int test_mixed_sign_mull_overflow(int x, unsigned y) {
|
||||||
|
// CHECK: @test_mixed_sign_mull_overflow
|
||||||
|
// CHECK: [[IsNeg:%.*]] = icmp slt i32 [[Op1:%.*]], 0
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
Name: %pkg_name
|
Name: %pkg_name
|
||||||
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
|
Version: %{maj_ver}.%{min_ver}.%{patch_ver}
|
||||||
Release: 1%{?rc_ver:.rc%{rc_ver}}%{?dist}
|
Release: 2%{?rc_ver:.rc%{rc_ver}}%{?dist}
|
||||||
Summary: A C language family front-end for LLVM
|
Summary: A C language family front-end for LLVM
|
||||||
|
|
||||||
License: NCSA
|
License: NCSA
|
||||||
@ -74,6 +74,8 @@ Patch4: 0001-gtest-reorg.patch
|
|||||||
Patch5: 0001-Don-t-prefer-python2.7.patch
|
Patch5: 0001-Don-t-prefer-python2.7.patch
|
||||||
Patch6: 0001-Convert-clang-format-diff.py-to-python3-using-2to3.patch
|
Patch6: 0001-Convert-clang-format-diff.py-to-python3-using-2to3.patch
|
||||||
Patch7: 0001-Convert-scan-view-to-python3-using-2to3.patch
|
Patch7: 0001-Convert-scan-view-to-python3-using-2to3.patch
|
||||||
|
#rhbz#1657544
|
||||||
|
Patch8: 0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch
|
||||||
|
|
||||||
# clang-tools-extra patches
|
# clang-tools-extra patches
|
||||||
Patch100: 0001-Convert-run-find-all-symbols.py-to-python3-using-2to.patch
|
Patch100: 0001-Convert-run-find-all-symbols.py-to-python3-using-2to.patch
|
||||||
@ -217,6 +219,7 @@ pathfix.py -i %{__python3} -pn \
|
|||||||
%patch5 -p1 -b .no-python2
|
%patch5 -p1 -b .no-python2
|
||||||
%patch6 -p1 -b .clang-format-diff-py3
|
%patch6 -p1 -b .clang-format-diff-py3
|
||||||
%patch7 -p1 -b .scan-view-py3
|
%patch7 -p1 -b .scan-view-py3
|
||||||
|
%patch8 -p1 -b .mul-overflow-fix
|
||||||
|
|
||||||
mv ../%{clang_tools_srcdir} tools/extra
|
mv ../%{clang_tools_srcdir} tools/extra
|
||||||
|
|
||||||
@ -416,6 +419,8 @@ false
|
|||||||
|
|
||||||
%endif
|
%endif
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Dec 19 2018 Tom Stellard <tstellar@redhat.com> - 7.0.1-2
|
||||||
|
- Fix for rhbz#1657544
|
||||||
|
|
||||||
* Tue Dec 18 2018 sguelton@redhat.com - 7.0.1-1
|
* Tue Dec 18 2018 sguelton@redhat.com - 7.0.1-1
|
||||||
- 7.0.1
|
- 7.0.1
|
||||||
|
@ -18,3 +18,6 @@
|
|||||||
- llvm-abi-test-suite:
|
- llvm-abi-test-suite:
|
||||||
dir: ./
|
dir: ./
|
||||||
run: cd /usr/share/llvm-test-suite/ABI-Testsuite/ && python2 linux-x86.py clang test -v --path /usr/lib64/llvm/ -j 1
|
run: cd /usr/share/llvm-test-suite/ABI-Testsuite/ && python2 linux-x86.py clang test -v --path /usr/lib64/llvm/ -j 1
|
||||||
|
- rhbz#1657544:
|
||||||
|
dir: ./from_chars
|
||||||
|
run: clang++ from_chars.cpp && ./a.out 100 | grep 100
|
||||||
|
Loading…
Reference in New Issue
Block a user