diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-05-22 23:02:11 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-05-22 23:02:11 +0000 |
| commit | 4c3753c4d483f8115df78507117a105438b42ec9 (patch) | |
| tree | 0ab5abf1241e0f189dd74055eadecb47a40ffd2a /llvm/test/Transforms/InstCombine | |
| parent | 25f82aae57d2ce48ad9cff8cb34a6c3dc10ad519 (diff) | |
| download | bcm5719-llvm-4c3753c4d483f8115df78507117a105438b42ec9.tar.gz bcm5719-llvm-4c3753c4d483f8115df78507117a105438b42ec9.zip | |
[InstCombine] Don't eagerly propagate nsw for A*B+A*C => A*(B+C)
InstCombine transforms A *nsw B +nsw A *nsw C to A *nsw (B + C).
This is incorrect -- e.g. if A = -1, B = 1, C = INT_SMAX. Then
nothing in the LHS overflows, but the multiplication in RHS overflows.
We need to first make sure that we won't multiple by INT_SMAX + 1.
Test case `add_of_mul` contributed by Sanjoy Das.
This fixes PR23635.
Differential Revision: http://reviews.llvm.org/D9629
llvm-svn: 238066
Diffstat (limited to 'llvm/test/Transforms/InstCombine')
| -rw-r--r-- | llvm/test/Transforms/InstCombine/add2.ll | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InstCombine/add2.ll b/llvm/test/Transforms/InstCombine/add2.ll index fbbba5954b3..1af2b0ffbf0 100644 --- a/llvm/test/Transforms/InstCombine/add2.ll +++ b/llvm/test/Transforms/InstCombine/add2.ll @@ -273,6 +273,35 @@ define i32 @mul_add_to_mul_6(i32 %x, i32 %y) { ; CHECK-NEXT: ret i32 %add } +define i16 @mul_add_to_mul_7(i16 %x) { + %mul1 = mul nsw i16 %x, 32767 + %add2 = add nsw i16 %x, %mul1 + ret i16 %add2 +; CHECK-LABEL: @mul_add_to_mul_7( +; CHECK-NEXT: %add2 = shl i16 %x, 15 +; CHECK-NEXT: ret i16 %add2 +} + +define i16 @mul_add_to_mul_8(i16 %a) { + %mul1 = mul nsw i16 %a, 16383 + %mul2 = mul nsw i16 %a, 16384 + %add = add nsw i16 %mul1, %mul2 + ret i16 %add +; CHECK-LABEL: @mul_add_to_mul_8( +; CHECK-NEXT: %add = mul nsw i16 %a, 32767 +; CHECK-NEXT: ret i16 %add +} + +define i16 @mul_add_to_mul_9(i16 %a) { + %mul1 = mul nsw i16 %a, 16384 + %mul2 = mul nsw i16 %a, 16384 + %add = add nsw i16 %mul1, %mul2 + ret i16 %add +; CHECK-LABEL: @mul_add_to_mul_9( +; CHECK-NEXT: %add = shl i16 %a, 15 +; CHECK-NEXT: ret i16 %add +} + ; This test and the next test verify that when a range metadata is attached to ; llvm.cttz, ValueTracking correctly intersects the range specified by the ; metadata and the range implied by the intrinsic. @@ -353,3 +382,16 @@ define i32 @add_nuw_nsw_or_and(i32 %x, i32 %y) { ; CHECK-NEXT: add nuw nsw i32 %x, %y ; CHECK-NEXT: ret i32 } + +; A *nsw B + A *nsw C != A *nsw (B + C) +; e.g. A = -1, B = 1, C = INT_SMAX + +define i8 @add_of_mul(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @add_of_mul( + entry: + %mA = mul nsw i8 %x, %y + %mB = mul nsw i8 %x, %z +; CHECK: %sum = mul i8 + %sum = add nsw i8 %mA, %mB + ret i8 %sum +} |

