From 4333f49afebb9b11291ac09538eabf12c7cbe81c Mon Sep 17 00:00:00 2001 From: Nick Lewycky <nicholas@mxc.ca> Date: Sat, 31 Jan 2009 21:30:05 +0000 Subject: [PATCH] Reinstate this optimization to fold icmp of xor when possible. Don't try to turn icmp eq a+x, b+x into icmp eq a, b if a+x or b+x has other uses. This may have been increasing register pressure leading to the bzip2 slowdown. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63487 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 55 +++++++++++++++++-- .../InstCombine/2008-08-17-ICmpXorSignbit.ll | 1 - .../InstCombine/2009-01-31-Pressure.ll | 22 ++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 test/Transforms/InstCombine/2009-01-31-Pressure.ll diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 8b9c5999477..a1cb3dc39fc 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -6095,18 +6095,40 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) { if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1)) { if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I->hasOneUse() && - Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1) && - I.isEquality()) { + Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1)) { switch (Op0I->getOpcode()) { default: break; case Instruction::Add: case Instruction::Sub: case Instruction::Xor: - // a+x icmp eq/ne b+x --> a icmp b - return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), - Op1I->getOperand(0)); + if (I.isEquality()) { + // a+x icmp eq/ne b+x --> a icmp b + return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), + Op1I->getOperand(0)); + } else { + // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b + if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) { + if (CI->getValue().isSignBit()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); + } else if ((~CI->getValue()).isSignBit()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + Pred = I.getSwappedPredicate(Pred); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); + } + } + } break; case Instruction::Mul: + if (!I.isEquality()) + break; + if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) { // a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask // Mask = -1 >> count-trailing-zeros(Cst). @@ -6425,6 +6447,29 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, else return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS)); } + + if (LHSI->hasOneUse()) { + // (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit)) + if (!ICI.isEquality() && XorCST->getValue().isSignBit()) { + const APInt &SignBit = XorCST->getValue(); + ICmpInst::Predicate Pred = ICI.isSignedPredicate() + ? ICI.getUnsignedPredicate() + : ICI.getSignedPredicate(); + return new ICmpInst(Pred, LHSI->getOperand(0), + ConstantInt::get(RHSV ^ SignBit)); + } + + // (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A) + if (!ICI.isEquality() && (~XorCST->getValue()).isSignBit()) { + const APInt &NotSignBit = XorCST->getValue(); + ICmpInst::Predicate Pred = ICI.isSignedPredicate() + ? ICI.getUnsignedPredicate() + : ICI.getSignedPredicate(); + Pred = ICI.getSwappedPredicate(Pred); + return new ICmpInst(Pred, LHSI->getOperand(0), + ConstantInt::get(RHSV ^ NotSignBit)); + } + } } break; case Instruction::And: // (icmp pred (and X, AndCST), RHS) diff --git a/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll b/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll index 1540d41a265..428a35947d1 100644 --- a/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll +++ b/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep xor -; XFAIL: * define i1 @test1(i8 %x, i8 %y) { %X = xor i8 %x, 128 diff --git a/test/Transforms/InstCombine/2009-01-31-Pressure.ll b/test/Transforms/InstCombine/2009-01-31-Pressure.ll new file mode 100644 index 00000000000..0c3066bb90c --- /dev/null +++ b/test/Transforms/InstCombine/2009-01-31-Pressure.ll @@ -0,0 +1,22 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%B = add i8 %b, %x} +; PR2698 + +declare void @use1(i1) +declare void @use8(i8) + +define void @test1(i8 %a, i8 %b, i8 %x) { + %A = add i8 %a, %x + %B = add i8 %b, %x + %C = icmp eq i8 %A, %B + call void @use1(i1 %C) + ret void +} + +define void @test2(i8 %a, i8 %b, i8 %x) { + %A = add i8 %a, %x + %B = add i8 %b, %x + %C = icmp eq i8 %A, %B + call void @use1(i1 %C) + call void @use8(i8 %A) + ret void +}