diff --git a/0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch b/0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch new file mode 100644 index 0000000..4c07bad --- /dev/null +++ b/0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch @@ -0,0 +1,122 @@ +From b9d6dba608ab50d2e4a1b0f2318a5d1b390fc702 Mon Sep 17 00:00:00 2001 +From: Vedant Kumar +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 + diff --git a/clang.spec b/clang.spec index f314789..a266e42 100644 --- a/clang.spec +++ b/clang.spec @@ -58,7 +58,7 @@ Name: %pkg_name 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 License: NCSA @@ -74,6 +74,8 @@ Patch4: 0001-gtest-reorg.patch Patch5: 0001-Don-t-prefer-python2.7.patch Patch6: 0001-Convert-clang-format-diff.py-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 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 %patch6 -p1 -b .clang-format-diff-py3 %patch7 -p1 -b .scan-view-py3 +%patch8 -p1 -b .mul-overflow-fix mv ../%{clang_tools_srcdir} tools/extra @@ -416,6 +419,8 @@ false %endif %changelog +* Wed Dec 19 2018 Tom Stellard - 7.0.1-2 +- Fix for rhbz#1657544 * Tue Dec 18 2018 sguelton@redhat.com - 7.0.1-1 - 7.0.1 diff --git a/tests/tests.yml b/tests/tests.yml index b3d34e3..3fb0db5 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -18,3 +18,6 @@ - llvm-abi-test-suite: dir: ./ 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