From c0ea535a72be278c99c75017e9a6d74a949bc17b Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 31 Jul 2018 12:31:00 +0000 Subject: [PATCH] [InstCombine] move/add tests for xor+add fold; NFC llvm-svn: 338364 --- test/Transforms/InstCombine/and-xor-or.ll | 94 +++++++++++++++++++++++ test/Transforms/InstCombine/and2.ll | 12 --- test/Transforms/InstCombine/xor.ll | 11 --- 3 files changed, 94 insertions(+), 23 deletions(-) diff --git a/test/Transforms/InstCombine/and-xor-or.ll b/test/Transforms/InstCombine/and-xor-or.ll index e4495fa5b0a..0557dd938fe 100644 --- a/test/Transforms/InstCombine/and-xor-or.ll +++ b/test/Transforms/InstCombine/and-xor-or.ll @@ -1,6 +1,100 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine -S | FileCheck %s +; a & (a ^ b) --> a & ~b + +define i32 @and_xor_common_op(i32 %pa, i32 %pb) { +; CHECK-LABEL: @and_xor_common_op( +; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]] +; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] +; CHECK-NEXT: ret i32 [[R]] +; + %a = udiv i32 42, %pa ; thwart complexity-based canonicalization + %b = udiv i32 43, %pb ; thwart complexity-based canonicalization + %xor = xor i32 %a, %b + %r = and i32 %a, %xor + ret i32 %r +} + +; a & (b ^ a) --> a & ~b + +define i32 @and_xor_common_op_commute1(i32 %pa, i32 %pb) { +; CHECK-LABEL: @and_xor_common_op_commute1( +; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]] +; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] +; CHECK-NEXT: ret i32 [[R]] +; + %a = udiv i32 42, %pa ; thwart complexity-based canonicalization + %b = udiv i32 43, %pb ; thwart complexity-based canonicalization + %xor = xor i32 %b, %a + %r = and i32 %a, %xor + ret i32 %r +} + +; (b ^ a) & a --> a & ~b + +define i32 @and_xor_common_op_commute2(i32 %pa, i32 %pb) { +; CHECK-LABEL: @and_xor_common_op_commute2( +; CHECK-NEXT: [[A:%.*]] = udiv i32 42, [[PA:%.*]] +; CHECK-NEXT: [[B:%.*]] = udiv i32 43, [[PB:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B]], -1 +; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], [[TMP1]] +; CHECK-NEXT: ret i32 [[R]] +; + %a = udiv i32 42, %pa ; thwart complexity-based canonicalization + %b = udiv i32 43, %pb ; thwart complexity-based canonicalization + %xor = xor i32 %b, %a + %r = and i32 %xor, %a + ret i32 %r +} + +; (a ^ b) & a --> a & ~b + +define <2 x i32> @and_xor_common_op_commute3(<2 x i32> %pa, <2 x i32> %pb) { +; CHECK-LABEL: @and_xor_common_op_commute3( +; CHECK-NEXT: [[A:%.*]] = udiv <2 x i32> , [[PA:%.*]] +; CHECK-NEXT: [[B:%.*]] = udiv <2 x i32> , [[PB:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[B]], +; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[A]], [[TMP1]] +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = udiv <2 x i32> , %pa ; thwart complexity-based canonicalization + %b = udiv <2 x i32> , %pb ; thwart complexity-based canonicalization + %xor = xor <2 x i32> %a, %b + %r = and <2 x i32> %xor, %a + ret <2 x i32> %r +} + +; It's ok to match a common constant. + +define <4 x i32> @and_xor_common_op_constant(<4 x i32> %A) { +; CHECK-LABEL: @and_xor_common_op_constant( +; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> [[A:%.*]], +; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[TMP1]], +; CHECK-NEXT: ret <4 x i32> [[TMP2]] +; + %1 = xor <4 x i32> %A, + %2 = and <4 x i32> , %1 + ret <4 x i32> %2 +} + +; a & (a ^ ~b) --> a & b + +define i32 @and_xor_not_common_op(i32 %a, i32 %b) { +; CHECK-LABEL: @and_xor_not_common_op( +; CHECK-NEXT: [[T4:%.*]] = and i32 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret i32 [[T4]] +; + %b2 = xor i32 %b, -1 + %t2 = xor i32 %a, %b2 + %t4 = and i32 %t2, %a + ret i32 %t4 +} + ; rdar://10770603 ; (x & y) | (x ^ y) -> x | y diff --git a/test/Transforms/InstCombine/and2.ll b/test/Transforms/InstCombine/and2.ll index dde786c9b00..ec23f61cb67 100644 --- a/test/Transforms/InstCombine/and2.ll +++ b/test/Transforms/InstCombine/and2.ll @@ -21,18 +21,6 @@ define i32 @test3(i32 %X, i32 %Y) { ret i32 %b } -; Make sure we don't go into an infinite loop with this test -define <4 x i32> @test5(<4 x i32> %A) { -; CHECK-LABEL: @test5( -; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i32> %A, -; CHECK-NEXT: [[TMP2:%.*]] = and <4 x i32> [[TMP1]], -; CHECK-NEXT: ret <4 x i32> [[TMP2]] -; - %1 = xor <4 x i32> %A, - %2 = and <4 x i32> , %1 - ret <4 x i32> %2 -} - define i1 @test7(i32 %i, i1 %b) { ; CHECK-LABEL: @test7( ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 %i, 0 diff --git a/test/Transforms/InstCombine/xor.ll b/test/Transforms/InstCombine/xor.ll index 0724af1f422..2fc5270587f 100644 --- a/test/Transforms/InstCombine/xor.ll +++ b/test/Transforms/InstCombine/xor.ll @@ -328,17 +328,6 @@ define i32 @test25(i32 %g, i32 %h) { ret i32 %t4 } -define i32 @test26(i32 %a, i32 %b) { -; CHECK-LABEL: @test26( -; CHECK-NEXT: [[T4:%.*]] = and i32 %b, %a -; CHECK-NEXT: ret i32 [[T4]] -; - %b2 = xor i32 %b, -1 - %t2 = xor i32 %a, %b2 - %t4 = and i32 %t2, %a - ret i32 %t4 -} - define i32 @test27(i32 %b, i32 %c, i32 %d) { ; CHECK-LABEL: @test27( ; CHECK-NEXT: [[T6:%.*]] = icmp eq i32 %b, %c