Merged to 6.0 in r322555.
On Thu, Jan 4, 2018 at 12:11 AM, Vedant Kumar via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: vedantk > Date: Wed Jan 3 15:11:32 2018 > New Revision: 321771 > > URL: http://llvm.org/viewvc/llvm-project?rev=321771&view=rev > Log: > [CGBuiltin] Handle unsigned mul overflow properly (PR35750) > > r320902 fixed the IRGen for some types of checked multiplications. It > did not handle unsigned overflow correctly in the case where the signed > operand is negative (PR35750). > > Eli pointed out that on overflow, the result must be equal to the unique > value that is equivalent to the mathematically-correct result modulo two > raised to the k power, where k is the number of bits in the result type. > > This patch fixes the specialized IRGen from r320902 accordingly. > > Testing: Apart from check-clang, I modified the test harness from > r320902 to validate the results of all multiplications -- not just the > ones which don't overflow: > > https://gist.github.com/vedantk/3eb9c88f82e5c32f2e590555b4af5081 > > llvm.org/PR35750, rdar://34963321 > > Differential Revision: https://reviews.llvm.org/D41717 > > Modified: > cfe/trunk/lib/CodeGen/CGBuiltin.cpp > cfe/trunk/test/CodeGen/builtins-overflow.c > > Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=321771&r1=321770&r2=321771&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed Jan 3 15:11:32 2018 > @@ -915,7 +915,11 @@ EmitCheckedMixedSignMultiply(CodeGenFunc > Overflow = CGF.Builder.CreateOr(Overflow, TruncOverflow); > } > > - Result = CGF.Builder.CreateTrunc(UnsignedResult, ResTy); > + // Negate the product if it would be negative in infinite precision. > + Result = CGF.Builder.CreateSelect( > + IsNegative, CGF.Builder.CreateNeg(UnsignedResult), UnsignedResult); > + > + Result = CGF.Builder.CreateTrunc(Result, ResTy); > } > assert(Overflow && Result && "Missing overflow or result"); > > > Modified: cfe/trunk/test/CodeGen/builtins-overflow.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-overflow.c?rev=321771&r1=321770&r2=321771&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGen/builtins-overflow.c (original) > +++ cfe/trunk/test/CodeGen/builtins-overflow.c Wed Jan 3 15:11:32 2018 > @@ -373,7 +373,9 @@ int test_mixed_sign_mull_overflow_unsign > // CHECK-NEXT: [[NotNull:%.*]] = icmp ne i32 [[UnsignedResult]], 0 > // CHECK-NEXT: [[Underflow:%.*]] = and i1 [[IsNeg]], [[NotNull]] > // CHECK-NEXT: [[OFlow:%.*]] = or i1 [[UnsignedOFlow]], [[Underflow]] > -// CHECK-NEXT: store i32 [[UnsignedResult]], i32* %{{.*}}, align 4 > +// CHECK-NEXT: [[NegatedResult:%.*]] = sub i32 0, [[UnsignedResult]] > +// CHECK-NEXT: [[Result:%.*]] = select i1 [[IsNeg]], i32 [[NegatedResult]], > i32 [[UnsignedResult]] > +// CHECK-NEXT: store i32 [[Result]], i32* %{{.*}}, align 4 > // CHECK: br i1 [[OFlow]] > > unsigned result; > @@ -432,7 +434,9 @@ long long test_mixed_sign_mulll_overflow > // CHECK-NEXT: [[OVERFLOW_PRE_TRUNC:%.*]] = or i1 {{.*}}, [[UNDERFLOW]] > // CHECK-NEXT: [[TRUNC_OVERFLOW:%.*]] = icmp ugt i64 [[UNSIGNED_RESULT]], > 4294967295 > // CHECK-NEXT: [[OVERFLOW:%.*]] = or i1 [[OVERFLOW_PRE_TRUNC]], > [[TRUNC_OVERFLOW]] > -// CHECK-NEXT: trunc i64 [[UNSIGNED_RESULT]] to i32 > +// CHECK-NEXT: [[NEGATED:%.*]] = sub i64 0, [[UNSIGNED_RESULT]] > +// CHECK-NEXT: [[RESULT:%.*]] = select i1 {{.*}}, i64 [[NEGATED]], i64 > [[UNSIGNED_RESULT]] > +// CHECK-NEXT: trunc i64 [[RESULT]] to i32 > // CHECK-NEXT: store > unsigned result; > if (__builtin_mul_overflow(y, x, &result)) > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits