#8 Fix for rhbz#1657544
Closed 5 years ago by tstellar. Opened 5 years ago by tstellar.
rpms/ tstellar/llvm rhbz1657544  into  f29

@@ -0,0 +1,122 @@ 

+ From f7e449be0f6ccf363380c33b3249055e36b76909 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

+ 

+ llvm-svn: 349542

+ ---

+  clang/lib/CodeGen/CGBuiltin.cpp        | 19 ++++++++++++++-----

+  clang/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

+ 

file modified
+5 -1
@@ -55,7 +55,7 @@ 

  

  Name:		%{pkg_name}

  Version:	%{maj_ver}.%{min_ver}.%{patch_ver}

- Release:	2%{?rc_ver:.rc%{rc_ver}}%{?dist}

+ Release:	3%{?rc_ver:.rc%{rc_ver}}%{?dist}

  Summary:	The Low Level Virtual Machine

  

  License:	NCSA
@@ -75,6 +75,7 @@ 

  

  Patch16:	0001-Ensure-that-variant-part-discriminator-is-read-by-Me.patch

  Patch17:	0002-test-Fix-Assembler-debug-info.ll.patch

+ Patch18:	0001-CodeGen-Handle-mixed-width-ops-in-mixed-sign-mul-wit.patch

  

  BuildRequires:	gcc

  BuildRequires:	gcc-c++
@@ -450,6 +451,9 @@ 

  %endif

  

  %changelog

+ * Tue Feb 12 2019 Tom Stellard <tstellar@redhat.com> - 7.0.1-3

+ - Fix for rhbz#1657544

+ 

  * Mon Jan 21 2019 Josh Stone <jistone@redhat.com> - 7.0.1-2

  - Fix discriminators in metadata, rhbz#1668033