summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/InstCombine
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-05-22 23:02:11 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-05-22 23:02:11 +0000
commit4c3753c4d483f8115df78507117a105438b42ec9 (patch)
tree0ab5abf1241e0f189dd74055eadecb47a40ffd2a /llvm/test/Transforms/InstCombine
parent25f82aae57d2ce48ad9cff8cb34a6c3dc10ad519 (diff)
downloadbcm5719-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.ll42
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
+}
OpenPOWER on IntegriCloud