[llvm] r201176 - InstCombine: Teach icmp merging about the equivalence of bit tests and UGE/ULT with a power of 2.
Jim Grosbach
grosbach at apple.com
Tue Feb 11 13:47:14 PST 2014
Clever. Does this help when building clang or llvm?
-Jim
On Feb 11, 2014, at 1:09 PM, Benjamin Kramer <benny.kra at googlemail.com> wrote:
> Author: d0k
> Date: Tue Feb 11 15:09:03 2014
> New Revision: 201176
>
> URL: http://llvm.org/viewvc/llvm-project?rev=201176&view=rev
> Log:
> InstCombine: Teach icmp merging about the equivalence of bit tests and UGE/ULT with a power of 2.
>
> This happens in bitfield code. While there reorganize the existing code
> a bit.
>
> Modified:
> llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=201176&r1=201175&r2=201176&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Tue Feb 11 15:09:03 2014
> @@ -503,31 +503,46 @@ static unsigned conjugateICmpMask(unsign
> /// decomposition fails.
> static bool decomposeBitTestICmp(const ICmpInst *I, ICmpInst::Predicate &Pred,
> Value *&X, Value *&Y, Value *&Z) {
> - // X < 0 is equivalent to (X & SignBit) != 0.
> - if (I->getPredicate() == ICmpInst::ICMP_SLT)
> - if (ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1)))
> - if (C->isZero()) {
> - X = I->getOperand(0);
> - Y = ConstantInt::get(I->getContext(),
> - APInt::getSignBit(C->getBitWidth()));
> - Pred = ICmpInst::ICMP_NE;
> - Z = C;
> - return true;
> - }
> + ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1));
> + if (!C)
> + return false;
>
> - // X > -1 is equivalent to (X & SignBit) == 0.
> - if (I->getPredicate() == ICmpInst::ICMP_SGT)
> - if (ConstantInt *C = dyn_cast<ConstantInt>(I->getOperand(1)))
> - if (C->isAllOnesValue()) {
> - X = I->getOperand(0);
> - Y = ConstantInt::get(I->getContext(),
> - APInt::getSignBit(C->getBitWidth()));
> - Pred = ICmpInst::ICMP_EQ;
> - Z = ConstantInt::getNullValue(C->getType());
> - return true;
> - }
> + switch (I->getPredicate()) {
> + default:
> + return false;
> + case ICmpInst::ICMP_SLT:
> + // X < 0 is equivalent to (X & SignBit) != 0.
> + if (!C->isZero())
> + return false;
> + Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
> + Pred = ICmpInst::ICMP_NE;
> + break;
> + case ICmpInst::ICMP_SGT:
> + // X > -1 is equivalent to (X & SignBit) == 0.
> + if (!C->isAllOnesValue())
> + return false;
> + Y = ConstantInt::get(I->getContext(), APInt::getSignBit(C->getBitWidth()));
> + Pred = ICmpInst::ICMP_EQ;
> + break;
> + case ICmpInst::ICMP_ULT:
> + // X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
> + if (!C->getValue().isPowerOf2())
> + return false;
> + Y = ConstantInt::get(I->getContext(), -C->getValue());
> + Pred = ICmpInst::ICMP_EQ;
> + break;
> + case ICmpInst::ICMP_UGT:
> + // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
> + if (!(C->getValue() + 1).isPowerOf2())
> + return false;
> + Y = ConstantInt::get(I->getContext(), ~C->getValue());
> + Pred = ICmpInst::ICMP_NE;
> + break;
> + }
>
> - return false;
> + X = I->getOperand(0);
> + Z = ConstantInt::getNullValue(C->getType());
> + return true;
> }
>
> /// foldLogOpOfMaskedICmpsHelper:
>
> Modified: llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll?rev=201176&r1=201175&r2=201176&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/sign-test-and-or.ll Tue Feb 11 15:09:03 2014
> @@ -177,3 +177,41 @@ if.then:
> if.end:
> ret void
> }
> +
> +define void @test10(i32 %a) nounwind {
> + %1 = and i32 %a, 2
> + %2 = icmp eq i32 %1, 0
> + %3 = icmp ult i32 %a, 4
> + %or.cond = and i1 %2, %3
> + br i1 %or.cond, label %if.then, label %if.end
> +
> +; CHECK-LABEL: @test10(
> +; CHECK-NEXT: %1 = icmp ult i32 %a, 2
> +; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
> +
> +if.then:
> + tail call void @foo() nounwind
> + ret void
> +
> +if.end:
> + ret void
> +}
> +
> +define void @test11(i32 %a) nounwind {
> + %1 = and i32 %a, 2
> + %2 = icmp ne i32 %1, 0
> + %3 = icmp ugt i32 %a, 3
> + %or.cond = or i1 %2, %3
> + br i1 %or.cond, label %if.then, label %if.end
> +
> +; CHECK-LABEL: @test11(
> +; CHECK-NEXT: %1 = icmp ugt i32 %a, 1
> +; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
> +
> +if.then:
> + tail call void @foo() nounwind
> + ret void
> +
> +if.end:
> + ret void
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list