[Reassociate] Add initial support for vector instructions.
[oota-llvm.git] / test / Transforms / InstCombine / add2.ll
index 821fce0dabcc89802f97f9df148aaa7ed7a5581d..fbbba5954b325518390c488fa4c9e70f22789589 100644 (file)
@@ -87,17 +87,22 @@ define i16 @test9(i16 %a) {
 ; CHECK-NEXT:  ret i16 %d
 }
 
-define i32 @test10(i32 %x) {
-  %x.not = or i32 %x, -1431655766
-  %neg = xor i32 %x.not, 1431655765
-  %add = add i32 %x, 1
+; y + (~((x >> 3) & 0x55555555) + 1) -> y - ((x >> 3) & 0x55555555)
+define i32 @test10(i32 %x, i32 %y) {
+  %shr = ashr i32 %x, 3
+  %shr.not = or i32 %shr, -1431655766
+  %neg = xor i32 %shr.not, 1431655765
+  %add = add i32 %y, 1
   %add1 = add i32 %add, %neg
   ret i32 %add1
 ; CHECK-LABEL: @test10(
-; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -1431655766
-; CHECK-NEXT: ret i32 [[AND]]
+; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
 }
 
+; y + (~(x & 0x55555555) + 1) -> y - (x & 0x55555555)
 define i32 @test11(i32 %x, i32 %y) {
   %x.not = or i32 %x, -1431655766
   %neg = xor i32 %x.not, 1431655765
@@ -110,20 +115,20 @@ define i32 @test11(i32 %x, i32 %y) {
 ; CHECK-NEXT: ret i32 [[SUB]]
 }
 
+; (y + 1) + ~(x & 0x55555555) -> y - (x & 0x55555555)
 define i32 @test12(i32 %x, i32 %y) {
-  %shr = ashr i32 %x, 3
-  %shr.not = or i32 %shr, -1431655766
-  %neg = xor i32 %shr.not, 1431655765
-  %add = add i32 %y, 1
-  %add1 = add i32 %add, %neg
+  %add = add nsw i32 %y, 1
+  %x.not = or i32 %x, -1431655766
+  %neg = xor i32 %x.not, 1431655765
+  %add1 = add nsw i32 %add, %neg
   ret i32 %add1
 ; CHECK-LABEL: @test12(
-; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
-; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655765
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765
 ; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
 ; CHECK-NEXT: ret i32 [[SUB]]
 }
 
+; y + (~(x & 0x55555556) + 1) -> y - (x & 0x55555556)
 define i32 @test13(i32 %x, i32 %y) {
   %x.not = or i32 %x, -1431655767
   %neg = xor i32 %x.not, 1431655766
@@ -136,16 +141,66 @@ define i32 @test13(i32 %x, i32 %y) {
 ; CHECK-NEXT: ret i32 [[SUB]]
 }
 
+; (y + 1) + ~(x & 0x55555556) -> y - (x & 0x55555556)
 define i32 @test14(i32 %x, i32 %y) {
-  %shr = ashr i32 %x, 3
-  %shr.not = or i32 %shr, -1431655767
-  %neg = xor i32 %shr.not, 1431655766
+  %add = add nsw i32 %y, 1
+  %x.not = or i32 %x, -1431655767
+  %neg = xor i32 %x.not, 1431655766
+  %add1 = add nsw i32 %add, %neg
+  ret i32 %add1
+; CHECK-LABEL: @test14(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x | 0x55555556) + 1) -> y - (x | 0x55555556)
+define i32 @test15(i32 %x, i32 %y) {
+  %x.not = and i32 %x, -1431655767
+  %neg = xor i32 %x.not, -1431655767
   %add = add i32 %y, 1
   %add1 = add i32 %add, %neg
   ret i32 %add1
-; CHECK-LABEL: @test14(
-; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
-; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655766
+; CHECK-LABEL: @test15(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x | 0x55555556) -> y - (x | 0x555555556)
+define i32 @test16(i32 %x, i32 %y) {
+  %add = add nsw i32 %y, 1
+  %x.not = and i32 %x, -1431655767
+  %neg = xor i32 %x.not, -1431655767
+  %add1 = add nsw i32 %add, %neg
+  ret i32 %add1
+; CHECK-LABEL: @test16(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; y + (~(x | 0x55555555) + 1) -> y - (x | 0x55555555)
+define i32 @test17(i32 %x, i32 %y) {
+  %x.not = and i32 %x, -1431655766
+  %add2 = xor i32 %x.not, -1431655765
+  %add1 = add nsw i32 %add2, %y
+  ret i32 %add1
+; CHECK-LABEL: @test17(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765
+; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
+; CHECK-NEXT: ret i32 [[SUB]]
+}
+
+; (y + 1) + ~(x | 0x55555555) -> y - (x | 0x55555555)
+define i32 @test18(i32 %x, i32 %y) {
+  %add = add nsw i32 %y, 1
+  %x.not = and i32 %x, -1431655766
+  %neg = xor i32 %x.not, -1431655766
+  %add1 = add nsw i32 %add, %neg
+  ret i32 %add1
+; CHECK-LABEL: @test18(
+; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765
 ; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]]
 ; CHECK-NEXT: ret i32 [[SUB]]
 }
@@ -239,7 +294,7 @@ define i16 @add_cttz(i16 %a) {
   ret i16 %b
 }
 declare i16 @llvm.cttz.i16(i16, i1)
-!0 = metadata !{i16 0, i16 8}
+!0 = !{i16 0, i16 8}
 
 ; Similar to @add_cttz, but in this test, the range implied by the
 ; intrinsic is more strict. Therefore, ValueTracking uses that range.
@@ -257,4 +312,44 @@ define i16 @add_cttz_2(i16 %a) {
 ; CHECK: or i16 %cttz, -16
   ret i16 %b
 }
-!1 = metadata !{i16 0, i16 32}
+!1 = !{i16 0, i16 32}
+
+define i32 @add_or_and(i32 %x, i32 %y) {
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %add = add i32 %or, %and
+  ret i32 %add
+; CHECK-LABEL: @add_or_and(
+; CHECK-NEXT: add i32 %x, %y
+; CHECK-NEXT: ret i32
+}
+
+define i32 @add_nsw_or_and(i32 %x, i32 %y) {
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %add = add nsw i32 %or, %and
+  ret i32 %add
+; CHECK-LABEL: @add_nsw_or_and(
+; CHECK-NEXT: add nsw i32 %x, %y
+; CHECK-NEXT: ret i32
+}
+
+define i32 @add_nuw_or_and(i32 %x, i32 %y) {
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %add = add nuw i32 %or, %and
+  ret i32 %add
+; CHECK-LABEL: @add_nuw_or_and(
+; CHECK-NEXT: add nuw i32 %x, %y
+; CHECK-NEXT: ret i32
+}
+
+define i32 @add_nuw_nsw_or_and(i32 %x, i32 %y) {
+  %or = or i32 %x, %y
+  %and = and i32 %x, %y
+  %add = add nsw nuw i32 %or, %and
+  ret i32 %add
+; CHECK-LABEL: @add_nuw_nsw_or_and(
+; CHECK-NEXT: add nuw nsw i32 %x, %y
+; CHECK-NEXT: ret i32
+}