From 0f70f86ce08f2535cb1cd9bffe159c55171f531d Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 4 Sep 2018 21:17:14 +0000 Subject: [PATCH] [InstCombine] make ((X & C) ^ C) form consistent for vectors It would be better to create a 'not' here, but that's not possible yet. llvm-svn: 341410 --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 6 ++---- llvm/test/Transforms/InstCombine/zext.ll | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 19322dd..202ec07 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2784,12 +2784,10 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return BinaryOperator::CreateAnd(Op0, Builder.CreateNot(X)); // (X & Y) ^ Y --> ~X & Y // (Y & X) ^ Y --> ~X & Y - // Canonical form with a non-splat constant is (X & C) ^ C; don't touch that. - // TODO: Why do we treat arbitrary vector constants differently? + // Canonical form is (X & C) ^ C; don't touch that. // TODO: A 'not' op is better for analysis and codegen, but demanded bits must // be fixed to prefer that (otherwise we get infinite looping). - const APInt *Unused; - if (!match(Op1, m_APInt(Unused)) && + if (!match(Op1, m_Constant()) && match(Op0, m_OneUse(m_c_And(m_Value(X), m_Specific(Op1))))) return BinaryOperator::CreateAnd(Op1, Builder.CreateNot(X)); diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll index 887d839..a53bf6c 100644 --- a/llvm/test/Transforms/InstCombine/zext.ll +++ b/llvm/test/Transforms/InstCombine/zext.ll @@ -35,8 +35,8 @@ define <2 x i64> @test3(<2 x i64> %A) { define <2 x i64> @test4(<2 x i64> %A) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i64> %A, -; CHECK-NEXT: [[XOR:%.*]] = and <2 x i64> [[TMP1]], +; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[A:%.*]], +; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i64> [[AND]], ; CHECK-NEXT: ret <2 x i64> [[XOR]] ; %trunc = trunc <2 x i64> %A to <2 x i32> -- 2.7.4