r321771 - [CGBuiltin] Handle unsigned mul overflow properly (PR35750)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 16 06:50:52 PST 2018


Merged to 6.0 in r322555.

On Thu, Jan 4, 2018 at 12:11 AM, Vedant Kumar via cfe-commits
<cfe-commits at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list