From 946e6ed8ac684741c0a5256d1a0b5667b32b236b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 6 Aug 2017 06:28:41 +0000 Subject: [PATCH] [InstCombine] Support ~(c-X) --> X+(-c-1) and ~(X-c) --> (-c-1)-X for splat vectors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310195 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineAndOrXor.cpp | 39 ++++++++++++------- .../Transforms/InstCombine/vec_phi_extract.ll | 2 +- test/Transforms/InstCombine/xor.ll | 30 ++++++++++++++ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 7b32812a2c1..e684f58f0f4 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2419,17 +2419,33 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return replaceInstUsesWith(I, Op0); } + { + const APInt *RHSC; + if (match(Op1, m_APInt(RHSC))) { + Value *V; + const APInt *C; + if (match(Op0, m_Sub(m_APInt(C), m_Value(V)))) { + // ~(c-X) == X-c-1 == X+(-c-1) + if (RHSC->isAllOnesValue()) { + Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1); + return BinaryOperator::CreateAdd(V, NewC); + } + } else if (match(Op0, m_Add(m_Value(V), m_APInt(C)))) { + // ~(X-c) --> (-c-1)-X + if (RHSC->isAllOnesValue()) { + Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1); + return BinaryOperator::CreateSub(NewC, V); + } + } + } + } + if (ConstantInt *RHSC = dyn_cast(Op1)) { if (BinaryOperator *Op0I = dyn_cast(Op0)) { - // ~(c-X) == X-c-1 == X+(-c-1) if (Op0I->getOpcode() == Instruction::Sub) if (ConstantInt *Op0I0C = dyn_cast(Op0I->getOperand(0))) { - if (RHSC->isMinusOne()) { - Constant *NegOp0I0C = ConstantExpr::getNeg(Op0I0C); - return BinaryOperator::CreateAdd(Op0I->getOperand(1), - SubOne(NegOp0I0C)); - } else if (RHSC->getValue().isSignMask()) { - // (C - X) ^ signmask -> (C + signmask - X) + // (C - X) ^ signmask -> (C + signmask - X) + if (RHSC->getValue().isSignMask()) { Constant *C = Builder.getInt(RHSC->getValue() + Op0I0C->getValue()); return BinaryOperator::CreateSub(C, Op0I->getOperand(1)); } @@ -2437,13 +2453,8 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) { if (Op0I->getOpcode() == Instruction::Add) { - // ~(X-c) --> (-c-1)-X - if (RHSC->isMinusOne()) { - Constant *NegOp0CI = ConstantExpr::getNeg(Op0CI); - return BinaryOperator::CreateSub(SubOne(NegOp0CI), - Op0I->getOperand(0)); - } else if (RHSC->getValue().isSignMask()) { - // (X + C) ^ signmask -> (X + C + signmask) + // (X + C) ^ signmask -> (X + C + signmask) + if (RHSC->getValue().isSignMask()) { Constant *C = Builder.getInt(RHSC->getValue() + Op0CI->getValue()); return BinaryOperator::CreateAdd(Op0I->getOperand(0), C); } diff --git a/test/Transforms/InstCombine/vec_phi_extract.ll b/test/Transforms/InstCombine/vec_phi_extract.ll index ea610b0b0ad..15eb94aad69 100644 --- a/test/Transforms/InstCombine/vec_phi_extract.ll +++ b/test/Transforms/InstCombine/vec_phi_extract.ll @@ -91,7 +91,7 @@ for.cond: %input_1.addr.1 = phi <3 x i32> [ undef, %entry ], [ %dec43, %for.body ] br i1 undef, label %for.end, label %for.body -; CHECK: extractelement <3 x i32> %{{.*}}, i32 0 +; CHECK-NOT: extractelement <3 x i32> %{{.*}}, i32 0 for.body: %dec43 = add <3 x i32> %input_1.addr.1, %sub44 = sub <3 x i32> , %dec43 diff --git a/test/Transforms/InstCombine/xor.ll b/test/Transforms/InstCombine/xor.ll index 5d4bd43512b..16757711427 100644 --- a/test/Transforms/InstCombine/xor.ll +++ b/test/Transforms/InstCombine/xor.ll @@ -188,6 +188,16 @@ define i32 @test15(i32 %A) { ret i32 %C } +define <2 x i32> @test15vec(<2 x i32> %A) { +; CHECK-LABEL: @test15vec( +; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> zeroinitializer, [[A:%.*]] +; CHECK-NEXT: ret <2 x i32> [[C]] +; + %B = add <2 x i32> %A, + %C = xor <2 x i32> %B, + ret <2 x i32> %C +} + define i32 @test16(i32 %A) { ; CHECK-LABEL: @test16( ; CHECK-NEXT: [[C:%.*]] = sub i32 -124, %A @@ -198,6 +208,16 @@ define i32 @test16(i32 %A) { ret i32 %C } +define <2 x i32> @test16vec(<2 x i32> %A) { +; CHECK-LABEL: @test16vec( +; CHECK-NEXT: [[C:%.*]] = sub <2 x i32> , [[A:%.*]] +; CHECK-NEXT: ret <2 x i32> [[C]] +; + %B = add <2 x i32> %A, + %C = xor <2 x i32> %B, + ret <2 x i32> %C +} + define i32 @test17(i32 %A) { ; CHECK-LABEL: @test17( ; CHECK-NEXT: [[C:%.*]] = add i32 %A, -124 @@ -208,6 +228,16 @@ define i32 @test17(i32 %A) { ret i32 %C } +define <2 x i32> @test17vec(<2 x i32> %A) { +; CHECK-LABEL: @test17vec( +; CHECK-NEXT: [[C:%.*]] = add <2 x i32> [[A:%.*]], +; CHECK-NEXT: ret <2 x i32> [[C]] +; + %B = sub <2 x i32> , %A + %C = xor <2 x i32> %B, + ret <2 x i32> %C +} + define i32 @test18(i32 %A) { ; CHECK-LABEL: @test18( ; CHECK-NEXT: [[C:%.*]] = add i32 %A, 124 -- 2.40.0