From 683e03d6d8158f9609ca2a098637e7c5ad13f66b Mon Sep 17 00:00:00 2001 From: "chenglin.bi" Date: Tue, 6 Dec 2022 00:31:58 +0800 Subject: [PATCH] [Instcombine] Precommit tests for some or canonicalization; NFC ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?) ~(A & B) ^ (A | ?) -> (A & B) | ~(A | ?) --- llvm/test/Transforms/InstCombine/xor2.ll | 232 ++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 6 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/xor2.ll b/llvm/test/Transforms/InstCombine/xor2.ll index 9f698b0..3871e1f 100644 --- a/llvm/test/Transforms/InstCombine/xor2.ll +++ b/llvm/test/Transforms/InstCombine/xor2.ll @@ -33,25 +33,25 @@ define i1 @test1(i32 %A) { } ; PR1014 -define i32 @test2(i32 %tmp1) { +define i32 @test2(i32 %t1) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32 +; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 32 ; CHECK-NEXT: [[OV1101:%.*]] = or i32 [[OVM]], 8 ; CHECK-NEXT: ret i32 [[OV1101]] ; - %ovm = and i32 %tmp1, 32 + %ovm = and i32 %t1, 32 %ov3 = add i32 %ovm, 145 %ov110 = xor i32 %ov3, 153 ret i32 %ov110 } -define i32 @test3(i32 %tmp1) { +define i32 @test3(i32 %t1) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[OVM:%.*]] = and i32 [[TMP1:%.*]], 32 +; CHECK-NEXT: [[OVM:%.*]] = and i32 [[T1:%.*]], 32 ; CHECK-NEXT: [[OV1101:%.*]] = or i32 [[OVM]], 8 ; CHECK-NEXT: ret i32 [[OV1101]] ; - %ovm = or i32 %tmp1, 145 + %ovm = or i32 %t1, 145 %ov31 = and i32 %ovm, 177 %ov110 = xor i32 %ov31, 153 ret i32 %ov110 @@ -519,3 +519,223 @@ define i8 @test16(i8 %A, i8 %B) { %res = mul i8 %and, %xor2 ; to increase the use count for the xor ret i8 %res } + +; TODO: Canonicalize ~((A & B) ^ (A | ?)) -> (A & B) | ~(A | ?) + +define i3 @not_xor_to_or_not1(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @not_xor_to_or_not1( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 +; CHECK-NEXT: ret i3 [[NOT]] +; + %or = or i3 %b, %c + %and = and i3 %a, %c + %xor = xor i3 %and, %or + %not = xor i3 %xor, -1 + ret i3 %not +} + +define i3 @not_xor_to_or_not2(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @not_xor_to_or_not2( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 +; CHECK-NEXT: ret i3 [[NOT]] +; + %or = or i3 %c, %b + %and = and i3 %a, %c + %xor = xor i3 %and, %or + %not = xor i3 %xor, -1 + ret i3 %not +} + +define i3 @not_xor_to_or_not3(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @not_xor_to_or_not3( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 +; CHECK-NEXT: ret i3 [[NOT]] +; + %or = or i3 %c, %b + %and = and i3 %c, %a + %xor = xor i3 %and, %or + %not = xor i3 %xor, -1 + ret i3 %not +} + +define i3 @not_xor_to_or_not4(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @not_xor_to_or_not4( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 +; CHECK-NEXT: ret i3 [[NOT]] +; + %or = or i3 %b, %c + %and = and i3 %c, %a + %xor = xor i3 %and, %or + %not = xor i3 %xor, -1 + ret i3 %not +} + +define <3 x i5> @not_xor_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { +; CHECK-LABEL: @not_xor_to_or_not_vector( +; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] +; CHECK-NEXT: [[XOR:%.*]] = xor <3 x i5> [[OR]], [[AND]] +; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i5> [[XOR]], +; CHECK-NEXT: ret <3 x i5> [[NOT]] +; + %or = or <3 x i5> %b, %c + %and = and <3 x i5> %a, %c + %xor = xor <3 x i5> %or, %and + %not = xor <3 x i5> %xor, + ret <3 x i5> %not +} + +define <3 x i5> @not_xor_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { +; CHECK-LABEL: @not_xor_to_or_not_vector_poison( +; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] +; CHECK-NEXT: [[XOR:%.*]] = xor <3 x i5> [[OR]], [[AND]] +; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i5> [[XOR]], +; CHECK-NEXT: ret <3 x i5> [[NOT]] +; + %or = or <3 x i5> %b, %c + %and = and <3 x i5> %a, %c + %xor = xor <3 x i5> %or, %and + %not = xor <3 x i5> %xor, + ret <3 x i5> %not +} + +define i3 @not_xor_to_or_not_2use(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @not_xor_to_or_not_2use( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[XOR]], -1 +; CHECK-NEXT: call void @use3(i3 [[XOR]]) +; CHECK-NEXT: ret i3 [[NOT]] +; + %or = or i3 %b, %c + %and = and i3 %a, %c + %xor = xor i3 %and, %or + %not = xor i3 %xor, -1 + call void @use3(i3 %xor) + ret i3 %not +} + +; TODO: Canonicalize ~(A & B) ^ (A | ?) -> (A & B) | ~(A | ?) + +define i3 @xor_notand_to_or_not1(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @xor_notand_to_or_not1( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[TMP1]], -1 +; CHECK-NEXT: ret i3 [[XOR]] +; + %or = or i3 %b, %c + %and = and i3 %a, %c + %not = xor i3 %and, -1 + %xor = xor i3 %not, %or + ret i3 %xor +} + +define i3 @xor_notand_to_or_not2(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @xor_notand_to_or_not2( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[TMP1]], -1 +; CHECK-NEXT: ret i3 [[XOR]] +; + %or = or i3 %c, %b + %and = and i3 %a, %c + %not = xor i3 %and, -1 + %xor = xor i3 %not, %or + ret i3 %xor +} + +define i3 @xor_notand_to_or_not3(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @xor_notand_to_or_not3( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[C:%.*]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[TMP1]], -1 +; CHECK-NEXT: ret i3 [[XOR]] +; + %or = or i3 %c, %b + %and = and i3 %c, %a + %not = xor i3 %and, -1 + %xor = xor i3 %not, %or + ret i3 %xor +} + +define i3 @xor_notand_to_or_not4(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @xor_notand_to_or_not4( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[C]], [[A:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i3 [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[TMP1]], -1 +; CHECK-NEXT: ret i3 [[XOR]] +; + %or = or i3 %b, %c + %and = and i3 %c, %a + %not = xor i3 %and, -1 + %xor = xor i3 %not, %or + ret i3 %xor +} + +define <3 x i5> @xor_notand_to_or_not_vector(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { +; CHECK-LABEL: @xor_notand_to_or_not_vector( +; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor <3 x i5> [[TMP1]], +; CHECK-NEXT: ret <3 x i5> [[XOR]] +; + %or = or <3 x i5> %b, %c + %and = and <3 x i5> %a, %c + %not = xor <3 x i5> %and, + %xor = xor <3 x i5> %not, %or + ret <3 x i5> %xor +} + +define <3 x i5> @xor_notand_to_or_not_vector_poison(<3 x i5> %a, <3 x i5> %b, <3 x i5> %c) { +; CHECK-LABEL: @xor_notand_to_or_not_vector_poison( +; CHECK-NEXT: [[OR:%.*]] = or <3 x i5> [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and <3 x i5> [[A:%.*]], [[C]] +; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i5> [[AND]], [[OR]] +; CHECK-NEXT: [[XOR:%.*]] = xor <3 x i5> [[TMP1]], +; CHECK-NEXT: ret <3 x i5> [[XOR]] +; + %or = or <3 x i5> %b, %c + %and = and <3 x i5> %a, %c + %not = xor <3 x i5> %and, + %xor = xor <3 x i5> %not, %or + ret <3 x i5> %xor +} + +define i3 @xor_notand_to_or_not_2use(i3 %a, i3 %b, i3 %c) { +; CHECK-LABEL: @xor_notand_to_or_not_2use( +; CHECK-NEXT: [[OR:%.*]] = or i3 [[B:%.*]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i3 [[A:%.*]], [[C]] +; CHECK-NEXT: [[NOT:%.*]] = xor i3 [[AND]], -1 +; CHECK-NEXT: [[XOR:%.*]] = xor i3 [[OR]], [[NOT]] +; CHECK-NEXT: call void @use3(i3 [[NOT]]) +; CHECK-NEXT: ret i3 [[XOR]] +; + %or = or i3 %b, %c + %and = and i3 %a, %c + %not = xor i3 %and, -1 + %xor = xor i3 %not, %or + call void @use3(i3 %not) + ret i3 %xor +} + +declare void @use3(i3) -- 2.7.4