diff options
author | Sanjay Patel <spatel@rotateright.com> | 2016-09-09 16:35:20 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2016-09-09 16:35:20 +0000 |
commit | 6da0fb8c74e16f26c4c96ab12a95975e3f1face7 (patch) | |
tree | abfbe711ecc11e15da7d22c8dfa795a509dfe0ed /llvm/test | |
parent | aa4adccc4dd2800aa15b5628a0ca77013c37ea53 (diff) | |
download | bcm5719-llvm-6da0fb8c74e16f26c4c96ab12a95975e3f1face7.tar.gz bcm5719-llvm-6da0fb8c74e16f26c4c96ab12a95975e3f1face7.zip |
[InstCombine] add tests to show pattern matching failures due to commutation
I was looking to fix a bug in getComplexity(), and these cases showed up as
obvious failures. I'm not sure how to find these in general though.
llvm-svn: 281055
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/Transforms/InstCombine/or-xor.ll | 55 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/or.ll | 55 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/xor2.ll | 38 |
3 files changed, 148 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InstCombine/or-xor.ll b/llvm/test/Transforms/InstCombine/or-xor.ll index 4765fcba755..3ba51de7108 100644 --- a/llvm/test/Transforms/InstCombine/or-xor.ll +++ b/llvm/test/Transforms/InstCombine/or-xor.ll @@ -140,6 +140,23 @@ define i32 @test12(i32 %x, i32 %y) { ret i32 %and } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test12_commuted(i32 %x, i32 %y) { +; CHECK-LABEL: @test12_commuted( +; CHECK-NEXT: [[NEG:%.*]] = xor i32 %x, -1 +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEG]], %y +; CHECK-NEXT: [[OR:%.*]] = or i32 %y, %x +; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[OR]] +; CHECK-NEXT: ret i32 [[AND]] +; + %neg = xor i32 %x, -1 + %xor = xor i32 %neg, %y + %or = or i32 %y, %x + %and = and i32 %xor, %or + ret i32 %and +} + ; ((x | y) ^ (x ^ y)) -> (x & y) define i32 @test13(i32 %x, i32 %y) { ; CHECK-LABEL: @test13( @@ -166,6 +183,25 @@ define i32 @test14(i32 %x, i32 %y) { ret i32 %xor } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test14_commuted(i32 %x, i32 %y) { +; CHECK-LABEL: @test14_commuted( +; CHECK-NEXT: [[NOTY:%.*]] = xor i32 %y, -1 +; CHECK-NEXT: [[NOTX:%.*]] = xor i32 %x, -1 +; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOTY]], %x +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOTX]], %y +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[OR1]], [[OR2]] +; CHECK-NEXT: ret i32 [[XOR]] +; + %noty = xor i32 %y, -1 + %notx = xor i32 %x, -1 + %or1 = or i32 %noty, %x + %or2 = or i32 %notx, %y + %xor = xor i32 %or1, %or2 + ret i32 %xor +} + ; ((x & ~y) ^ (~x & y)) -> x ^ y define i32 @test15(i32 %x, i32 %y) { ; CHECK-LABEL: @test15( @@ -180,6 +216,25 @@ define i32 @test15(i32 %x, i32 %y) { ret i32 %xor } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test15_commuted(i32 %x, i32 %y) { +; CHECK-LABEL: @test15_commuted( +; CHECK-NEXT: [[NOTY:%.*]] = xor i32 %y, -1 +; CHECK-NEXT: [[NOTX:%.*]] = xor i32 %x, -1 +; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NOTY]], %x +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NOTX]], %y +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND1]], [[AND2]] +; CHECK-NEXT: ret i32 [[XOR]] +; + %noty = xor i32 %y, -1 + %notx = xor i32 %x, -1 + %and1 = and i32 %noty, %x + %and2 = and i32 %notx, %y + %xor = xor i32 %and1, %and2 + ret i32 %xor +} + define i32 @test16(i32 %a, i32 %b) { ; CHECK-LABEL: @test16( ; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, 1 diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll index 4fb1978615d..38b8ebc5adf 100644 --- a/llvm/test/Transforms/InstCombine/or.ll +++ b/llvm/test/Transforms/InstCombine/or.ll @@ -555,6 +555,8 @@ define i32 @test41(i32 %a, i32 %b) { ret i32 %or } +; (~A ^ B) | (A & B) -> (~A ^ B) + define i32 @test42(i32 %a, i32 %b) { ; CHECK-LABEL: @test42( ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 %a, -1 @@ -568,6 +570,42 @@ define i32 @test42(i32 %a, i32 %b) { ret i32 %or } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test42_commuted_and(i32 %a, i32 %b) { +; CHECK-LABEL: @test42_commuted_and( +; CHECK-NEXT: [[NEGA:%.*]] = xor i32 %a, -1 +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], %b +; CHECK-NEXT: [[AND:%.*]] = and i32 %b, %a +; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]] +; CHECK-NEXT: ret i32 [[OR]] +; + %nega = xor i32 %a, -1 + %xor = xor i32 %nega, %b + %and = and i32 %b, %a + %or = or i32 %xor, %and + ret i32 %or +} + +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test42_commuted_xor(i32 %a, i32 %b) { +; CHECK-LABEL: @test42_commuted_xor( +; CHECK-NEXT: [[NEGA:%.*]] = xor i32 %a, -1 +; CHECK-NEXT: [[XOR:%.*]] = xor i32 %b, [[NEGA]] +; CHECK-NEXT: [[AND:%.*]] = and i32 %a, %b +; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]] +; CHECK-NEXT: ret i32 [[OR]] +; + %nega = xor i32 %a, -1 + %xor = xor i32 %b, %nega + %and = and i32 %a, %b + %or = or i32 %xor, %and + ret i32 %or +} + +; Commute operands of the 'or'. + define i32 @test43(i32 %a, i32 %b) { ; CHECK-LABEL: @test43( ; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b @@ -580,6 +618,23 @@ define i32 @test43(i32 %a, i32 %b) { ret i32 %or } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test43_commuted_and(i32 %a, i32 %b) { +; CHECK-LABEL: @test43_commuted_and( +; CHECK-NEXT: [[NEG:%.*]] = xor i32 %b, -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEG]], %a +; CHECK-NEXT: [[XOR:%.*]] = xor i32 %a, %b +; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XOR]] +; CHECK-NEXT: ret i32 [[OR]] +; + %neg = xor i32 %b, -1 + %and = and i32 %neg, %a + %xor = xor i32 %a, %b + %or = or i32 %and, %xor + ret i32 %or +} + define i32 @test44(i32 %a, i32 %b) { ; CHECK-LABEL: @test44( ; CHECK-NEXT: [[OR:%.*]] = xor i32 %a, %b diff --git a/llvm/test/Transforms/InstCombine/xor2.ll b/llvm/test/Transforms/InstCombine/xor2.ll index 7969d8f3a9a..7ec84d8caf9 100644 --- a/llvm/test/Transforms/InstCombine/xor2.ll +++ b/llvm/test/Transforms/InstCombine/xor2.ll @@ -180,6 +180,27 @@ define i32 @test12(i32 %a, i32 %b) { ret i32 %xor } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test12commuted(i32 %a, i32 %b) { +; CHECK-LABEL: @test12commuted( +; CHECK-NEXT: [[NEGB:%.*]] = xor i32 %b, -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEGB]], %a +; CHECK-NEXT: [[NEGA:%.*]] = xor i32 %a, -1 +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND]], [[NEGA]] +; CHECK-NEXT: ret i32 [[XOR]] +; + %negb = xor i32 %b, -1 + %and = and i32 %negb, %a + %nega = xor i32 %a, -1 + %xor = xor i32 %and, %nega + ret i32 %xor +} + +; This is a test of canonicalization via operand complexity. +; The final xor has a binary operator and a (fake) unary operator, +; so binary (more complex) should come first. + define i32 @test13(i32 %a, i32 %b) { ; CHECK-LABEL: @test13( ; CHECK-NEXT: [[TMP1:%.*]] = and i32 %a, %b @@ -193,6 +214,23 @@ define i32 @test13(i32 %a, i32 %b) { ret i32 %xor } +; FIXME: We miss the fold because the pattern matching is inadequate. + +define i32 @test13commuted(i32 %a, i32 %b) { +; CHECK-LABEL: @test13commuted( +; CHECK-NEXT: [[NEGA:%.*]] = xor i32 %a, -1 +; CHECK-NEXT: [[NEGB:%.*]] = xor i32 %b, -1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[NEGB]], %a +; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[AND]], [[NEGA]] +; CHECK-NEXT: ret i32 [[XOR]] +; + %nega = xor i32 %a, -1 + %negb = xor i32 %b, -1 + %and = and i32 %negb, %a + %xor = xor i32 %nega, %and + ret i32 %xor +} + ; (A ^ C) ^ (A | B) -> ((~A) & B) ^ C define i32 @test14(i32 %a, i32 %b, i32 %c) { ; CHECK-LABEL: @test14( |