diff --git a/test/Transforms/InstCombine/and-or-not.ll b/test/Transforms/InstCombine/and-or-not.ll index 5ce59008d7d..10bd5df59f4 100644 --- a/test/Transforms/InstCombine/and-or-not.ll +++ b/test/Transforms/InstCombine/and-or-not.ll @@ -70,6 +70,93 @@ define <4 x i32> @and_to_xor1_vec(<4 x i32> %a, <4 x i32> %b) { ret <4 x i32> %and2 } +; In the next 4 tests, cast instructions are used to thwart operand complexity +; canonicalizations, so we can test all of the commuted patterns. + +define i32 @and_to_nxor1(float %fa, float %fb) { +; CHECK-LABEL: @and_to_nxor1( +; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32 +; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32 +; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOTB]] +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOTA]], [[B]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR1]], [[OR2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %a = fptosi float %fa to i32 + %b = fptosi float %fb to i32 + %nota = xor i32 %a, -1 + %notb = xor i32 %b, -1 + %or1 = or i32 %a, %notb + %or2 = or i32 %nota, %b + %and = and i32 %or1, %or2 + ret i32 %and +} + +define i32 @and_to_nxor2(float %fa, float %fb) { +; CHECK-LABEL: @and_to_nxor2( +; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32 +; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32 +; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[OR1:%.*]] = or i32 [[A]], [[NOTB]] +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[B]], [[NOTA]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR1]], [[OR2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %a = fptosi float %fa to i32 + %b = fptosi float %fb to i32 + %nota = xor i32 %a, -1 + %notb = xor i32 %b, -1 + %or1 = or i32 %a, %notb + %or2 = or i32 %b, %nota + %and = and i32 %or1, %or2 + ret i32 %and +} + +define i32 @and_to_nxor3(float %fa, float %fb) { +; CHECK-LABEL: @and_to_nxor3( +; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32 +; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32 +; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOTA]], [[B]] +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[A]], [[NOTB]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR1]], [[OR2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %a = fptosi float %fa to i32 + %b = fptosi float %fb to i32 + %nota = xor i32 %a, -1 + %notb = xor i32 %b, -1 + %or1 = or i32 %nota, %b + %or2 = or i32 %a, %notb + %and = and i32 %or1, %or2 + ret i32 %and +} + +define i32 @and_to_nxor4(float %fa, float %fb) { +; CHECK-LABEL: @and_to_nxor4( +; CHECK-NEXT: [[A:%.*]] = fptosi float %fa to i32 +; CHECK-NEXT: [[B:%.*]] = fptosi float %fb to i32 +; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[OR1:%.*]] = or i32 [[NOTA]], [[B]] +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[NOTB]], [[A]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR1]], [[OR2]] +; CHECK-NEXT: ret i32 [[AND]] +; + %a = fptosi float %fa to i32 + %b = fptosi float %fb to i32 + %nota = xor i32 %a, -1 + %notb = xor i32 %b, -1 + %or1 = or i32 %nota, %b + %or2 = or i32 %notb, %a + %and = and i32 %or1, %or2 + ret i32 %and +} + ; (a & ~b) | (~a & b) --> a ^ b define i32 @or_to_xor1(float %fa, float %fb) { @@ -146,6 +233,66 @@ define i32 @or_to_xor4(float %fa, float %fb) { ret i32 %or } +define i32 @or_to_nxor1(i32 %a, i32 %b) { +; CHECK-LABEL: @or_to_nxor1( +; CHECK-NEXT: [[AND:%.*]] = and i32 %a, %b +; CHECK-NEXT: [[OR:%.*]] = or i32 %a, %b +; CHECK-NEXT: [[NOTOR:%.*]] = xor i32 [[OR]], -1 +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND]], [[NOTOR]] +; CHECK-NEXT: ret i32 [[OR2]] +; + %and = and i32 %a, %b + %or = or i32 %a, %b + %notor = xor i32 %or, -1 + %or2 = or i32 %and, %notor + ret i32 %or2 +} + +define i32 @or_to_nxor2(i32 %a, i32 %b) { +; CHECK-LABEL: @or_to_nxor2( +; CHECK-NEXT: [[AND:%.*]] = and i32 %a, %b +; CHECK-NEXT: [[OR:%.*]] = or i32 %b, %a +; CHECK-NEXT: [[NOTOR:%.*]] = xor i32 [[OR]], -1 +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND]], [[NOTOR]] +; CHECK-NEXT: ret i32 [[OR2]] +; + %and = and i32 %a, %b + %or = or i32 %b, %a + %notor = xor i32 %or, -1 + %or2 = or i32 %and, %notor + ret i32 %or2 +} + +define i32 @or_to_nxor3(i32 %a, i32 %b) { +; CHECK-LABEL: @or_to_nxor3( +; CHECK-NEXT: [[AND:%.*]] = and i32 %a, %b +; CHECK-NEXT: [[OR:%.*]] = or i32 %a, %b +; CHECK-NEXT: [[NOTOR:%.*]] = xor i32 [[OR]], -1 +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND]], [[NOTOR]] +; CHECK-NEXT: ret i32 [[OR2]] +; + %and = and i32 %a, %b + %or = or i32 %a, %b + %notor = xor i32 %or, -1 + %or2 = or i32 %notor, %and + ret i32 %or2 +} + +define i32 @or_to_nxor4(i32 %a, i32 %b) { +; CHECK-LABEL: @or_to_nxor4( +; CHECK-NEXT: [[AND:%.*]] = and i32 %b, %a +; CHECK-NEXT: [[OR:%.*]] = or i32 %a, %b +; CHECK-NEXT: [[NOTOR:%.*]] = xor i32 [[OR]], -1 +; CHECK-NEXT: [[OR2:%.*]] = or i32 [[AND]], [[NOTOR]] +; CHECK-NEXT: ret i32 [[OR2]] +; + %and = and i32 %b, %a + %or = or i32 %a, %b + %notor = xor i32 %or, -1 + %or2 = or i32 %notor, %and + ret i32 %or2 +} + ; (a & b) ^ (a | b) --> a ^ b define i32 @xor_to_xor1(i32 %a, i32 %b) { diff --git a/test/Transforms/InstCombine/or-to-xor.ll b/test/Transforms/InstCombine/or-to-xor.ll deleted file mode 100644 index 84567906f84..00000000000 --- a/test/Transforms/InstCombine/or-to-xor.ll +++ /dev/null @@ -1,55 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S | FileCheck %s - -define i32 @func1(i32 %a, i32 %b) { -; CHECK-LABEL: @func1( -; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b -; CHECK-NEXT: ret i32 [[T2]] -; - %b_not = xor i32 %b, -1 - %t0 = and i32 %a, %b_not - %a_not = xor i32 %a, -1 - %t1 = and i32 %a_not, %b - %t2 = or i32 %t0, %t1 - ret i32 %t2 -} - -define i32 @func2(i32 %a, i32 %b) { -; CHECK-LABEL: @func2( -; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b -; CHECK-NEXT: ret i32 [[T2]] -; - %b_not = xor i32 %b, -1 - %t0 = and i32 %b_not, %a - %a_not = xor i32 %a, -1 - %t1 = and i32 %a_not, %b - %t2 = or i32 %t0, %t1 - ret i32 %t2 -} - -define i32 @func3(i32 %a, i32 %b) { -; CHECK-LABEL: @func3( -; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b -; CHECK-NEXT: ret i32 [[T2]] -; - %b_not = xor i32 %b, -1 - %t0 = and i32 %a, %b_not - %a_not = xor i32 %a, -1 - %t1 = and i32 %b, %a_not - %t2 = or i32 %t0, %t1 - ret i32 %t2 -} - -define i32 @func4(i32 %a, i32 %b) { -; CHECK-LABEL: @func4( -; CHECK-NEXT: [[T2:%.*]] = xor i32 %a, %b -; CHECK-NEXT: ret i32 [[T2]] -; - %b_not = xor i32 %b, -1 - %t0 = and i32 %b_not, %a - %a_not = xor i32 %a, -1 - %t1 = and i32 %b, %a_not - %t2 = or i32 %t0, %t1 - ret i32 %t2 -} -