Added instruction combine to transform few more negative values addition to subtraction (Part 3)

This patch enables transforms for

(x + (~(y | c) + 1) --> x - (y | c) if c is odd

Differential Revision: http://reviews.llvm.org/D4210



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211881 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dinesh Dwivedi
2014-06-27 07:47:35 +00:00
parent 4299a8b4ba
commit 22e371c74e
2 changed files with 121 additions and 78 deletions

View 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,43 +141,67 @@ 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 i32 %y, 1
%add1 = add i32 %add, %neg
%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: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655766
; 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
%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: @test15(
; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 1431655766
; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[OR]]
; 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) {
%shr = ashr i32 %x, 3
%shr.not = and i32 %shr, -1431655767
%neg = xor i32 %shr.not, -1431655767
%add = add i32 %y, 1
%add1 = add i32 %add, %neg
ret i32 %add1
%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: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3
; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 [[SHR]], 1431655766
; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[OR]]
; 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]]
}