From: Craig Topper Date: Sun, 6 Aug 2017 22:17:21 +0000 (+0000) Subject: [InstCombine] Support '(C - X) ^ signmask -> (C + signmask - X)' and '(X + C) ^ signm... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6b4cc4f3b521eb4d390d619ba104ba7262f7c7d2;p=llvm [InstCombine] Support '(C - X) ^ signmask -> (C + signmask - X)' and '(X + C) ^ signmask -> (X + C + signmask)' for vector splats. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310232 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index e684f58f0f4..a2666f46349 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2430,35 +2430,30 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { Constant *NewC = ConstantInt::get(I.getType(), -(*C) - 1); return BinaryOperator::CreateAdd(V, NewC); } + if (RHSC->isSignMask()) { + // (C - X) ^ signmask -> (C + signmask - X) + Constant *NewC = ConstantInt::get(I.getType(), *C + *RHSC); + return BinaryOperator::CreateSub(NewC, V); + } } 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 (RHSC->isSignMask()) { + // (X + C) ^ signmask -> (X + C + signmask) + Constant *NewC = ConstantInt::get(I.getType(), *C + *RHSC); + return BinaryOperator::CreateAdd(V, NewC); + } } } } if (ConstantInt *RHSC = dyn_cast(Op1)) { if (BinaryOperator *Op0I = dyn_cast(Op0)) { - if (Op0I->getOpcode() == Instruction::Sub) - if (ConstantInt *Op0I0C = dyn_cast(Op0I->getOperand(0))) { - // (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)); - } - } - if (ConstantInt *Op0CI = dyn_cast(Op0I->getOperand(1))) { - if (Op0I->getOpcode() == Instruction::Add) { - // (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); - } - } else if (Op0I->getOpcode() == Instruction::Or) { + if (Op0I->getOpcode() == Instruction::Or) { // (X|C1)^C2 -> X^(C1|C2) iff X&~C1 == 0 if (MaskedValueIsZero(Op0I->getOperand(0), Op0CI->getValue(), 0, &I)) { diff --git a/test/Transforms/InstCombine/xor.ll b/test/Transforms/InstCombine/xor.ll index 16757711427..a26a089be62 100644 --- a/test/Transforms/InstCombine/xor.ll +++ b/test/Transforms/InstCombine/xor.ll @@ -383,6 +383,16 @@ define i32 @test28(i32 %indvar) { ret i32 %t214 } +define <2 x i32> @test28vec(<2 x i32> %indvar) { +; CHECK-LABEL: @test28vec( +; CHECK-NEXT: [[T214:%.*]] = add <2 x i32> [[INDVAR:%.*]], +; CHECK-NEXT: ret <2 x i32> [[T214]] +; + %t7 = add <2 x i32> %indvar, + %t214 = xor <2 x i32> %t7, + ret <2 x i32> %t214 +} + define i32 @test28_sub(i32 %indvar) { ; CHECK-LABEL: @test28_sub( ; CHECK-NEXT: [[T214:%.*]] = sub i32 1, [[INDVAR:%.*]] @@ -393,6 +403,16 @@ define i32 @test28_sub(i32 %indvar) { ret i32 %t214 } +define <2 x i32> @test28_subvec(<2 x i32> %indvar) { +; CHECK-LABEL: @test28_subvec( +; CHECK-NEXT: [[T214:%.*]] = sub <2 x i32> , [[INDVAR:%.*]] +; CHECK-NEXT: ret <2 x i32> [[T214]] +; + %t7 = sub <2 x i32> , %indvar + %t214 = xor <2 x i32> %t7, + ret <2 x i32> %t214 +} + define i32 @test29(i1 %C) { ; CHECK-LABEL: @test29( ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], i32 915, i32 113