[InstSimplify] Add tests for (~A & B) | ~(A | B) --> ~A with logical And. NFC
authorDavid Green <david.green@arm.com>
Mon, 7 Nov 2022 09:04:06 +0000 (09:04 +0000)
committerDavid Green <david.green@arm.com>
Mon, 7 Nov 2022 09:04:06 +0000 (09:04 +0000)
llvm/test/Transforms/InstCombine/or.ll
llvm/test/Transforms/InstSimplify/or.ll

index 3840939..fa10eef 100644 (file)
@@ -1561,3 +1561,24 @@ define i32 @mul_common_bits(i32 %p) {
   %r = or i32 %m, %x
   ret i32 %r
 }
+
+define <4 x i1> @and_or_not_or_logical_vec(<4 x i32> %ap, <4 x i32> %bp) {
+; CHECK-LABEL: @and_or_not_or_logical_vec(
+; CHECK-NEXT:    [[A:%.*]] = icmp eq <4 x i32> [[AP:%.*]], zeroinitializer
+; CHECK-NEXT:    [[B:%.*]] = icmp eq <4 x i32> [[BP:%.*]], zeroinitializer
+; CHECK-NEXT:    [[V:%.*]] = xor <4 x i1> [[A]], <i1 true, i1 true, i1 true, i1 true>
+; CHECK-NEXT:    [[X:%.*]] = select <4 x i1> [[B]], <4 x i1> [[V]], <4 x i1> zeroinitializer
+; CHECK-NEXT:    [[W:%.*]] = or <4 x i1> [[B]], [[A]]
+; CHECK-NEXT:    [[Y:%.*]] = xor <4 x i1> [[W]], <i1 true, i1 true, i1 true, i1 true>
+; CHECK-NEXT:    [[Z:%.*]] = or <4 x i1> [[X]], [[Y]]
+; CHECK-NEXT:    ret <4 x i1> [[Z]]
+;
+  %A = icmp eq <4 x i32> %ap, zeroinitializer
+  %B = icmp eq <4 x i32> %bp, zeroinitializer
+  %V = xor <4 x i1> %A, <i1 true, i1 true, i1 true, i1 true>
+  %X = select <4 x i1> %B, <4 x i1> %V, <4 x i1> zeroinitializer
+  %W = or <4 x i1> %B, %A
+  %Y = xor <4 x i1> %W, <i1 true, i1 true, i1 true, i1 true>
+  %Z = or <4 x i1> %X, %Y
+  ret <4 x i1> %Z
+}
index a279cab..ddfa85c 100644 (file)
@@ -454,6 +454,60 @@ define <2 x i4> @and_or_not_or_commute7(<2 x i4> %A, <2 x i4> %B) {
   ret <2 x i4> %r
 }
 
+; (~A & B) | ~(A | B) --> ~A with logical and
+define i1 @and_or_not_or_logical(i1 %A, i1 %B) {
+; CHECK-LABEL: @and_or_not_or_logical(
+; CHECK-NEXT:    [[V:%.*]] = xor i1 [[A:%.*]], true
+; CHECK-NEXT:    [[X:%.*]] = select i1 [[V]], i1 [[B:%.*]], i1 false
+; CHECK-NEXT:    [[W:%.*]] = or i1 [[B]], [[A]]
+; CHECK-NEXT:    [[Y:%.*]] = xor i1 [[W]], true
+; CHECK-NEXT:    [[Z:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[Z]]
+;
+  %V = xor i1 %A, true
+  %X = select i1 %V, i1 %B, i1 false
+  %W = or i1 %B, %A
+  %Y = xor i1 %W, true
+  %Z = or i1 %X, %Y
+  ret i1 %Z
+}
+
+; (~B & A) | ~(A | B) --> ~A with logical and
+define i1 @and_or_not_or_logical_rev(i1 %A, i1 %B) {
+; CHECK-LABEL: @and_or_not_or_logical_rev(
+; CHECK-NEXT:    [[V:%.*]] = xor i1 [[A:%.*]], true
+; CHECK-NEXT:    [[X:%.*]] = select i1 [[B:%.*]], i1 [[V]], i1 false
+; CHECK-NEXT:    [[W:%.*]] = or i1 [[B]], [[A]]
+; CHECK-NEXT:    [[Y:%.*]] = xor i1 [[W]], true
+; CHECK-NEXT:    [[Z:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[Z]]
+;
+  %V = xor i1 %A, true
+  %X = select i1 %B, i1 %V, i1 false
+  %W = or i1 %B, %A
+  %Y = xor i1 %W, true
+  %Z = or i1 %X, %Y
+  ret i1 %Z
+}
+
+; (~A & B) | ~(A | B) --> ~A with logical And and logical Or
+define i1 @and_or_not_logical_or_logical_rev(i1 %A, i1 %B) {
+; CHECK-LABEL: @and_or_not_logical_or_logical_rev(
+; CHECK-NEXT:    [[V:%.*]] = xor i1 [[A:%.*]], true
+; CHECK-NEXT:    [[X:%.*]] = select i1 [[B:%.*]], i1 [[V]], i1 false
+; CHECK-NEXT:    [[W:%.*]] = select i1 [[B]], i1 true, i1 [[A]]
+; CHECK-NEXT:    [[Y:%.*]] = xor i1 [[W]], true
+; CHECK-NEXT:    [[Z:%.*]] = or i1 [[X]], [[Y]]
+; CHECK-NEXT:    ret i1 [[Z]]
+;
+  %V = xor i1 %A, true
+  %X = select i1 %B, i1 %V, i1 false
+  %W = select i1 %B, i1 true, i1 %A
+  %Y = xor i1 %W, true
+  %Z = or i1 %X, %Y
+  ret i1 %Z
+}
+
 ; negative test - It is not safe to propagate an undef element from the 'not' op.
 
 define <2 x i4> @and_or_not_or_commute7_undef_elt(<2 x i4> %A, <2 x i4> %B) {