[PATCH] [InstCombine] Constant comparison involving "lshr exact"
Rafael EspĂndola
rafael.espindola at gmail.com
Mon Jun 2 12:29:40 PDT 2014
r210040
On 2 June 2014 13:53, Rahul Jain <rahul1.jain at samsung.com> wrote:
>
> Thanks Rafael, updated patch.
>
> Please if you could commit the same for me.
>
> Thanks a lot for your help!
>
> Rahul
>
> http://reviews.llvm.org/D3987
>
> Files:
> lib/Transforms/InstCombine/InstCombineCompares.cpp
> test/Transforms/InstCombine/icmp.ll
>
> Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
> ===================================================================
> --- lib/Transforms/InstCombine/InstCombineCompares.cpp
> +++ lib/Transforms/InstCombine/InstCombineCompares.cpp
> @@ -2318,6 +2318,32 @@
> return GlobalSwapBenefits > 0;
> }
>
> +// Helper function to check whether Op represents a lshr/ashr exact
> +// instruction. For example:
> +// (icmp (ashr exact const2, A), const1) -> icmp A, Log2(const2/const1)
> +// Here if Op represents -> (ashr exact const2, A), and CI represents
> +// const1, we compute Quotient as const2/const1.
> +
> +static bool checkShrExact(Value *Op, APInt &Quotient, const ConstantInt *CI,
> + Value *&A) {
> +
> + ConstantInt *CI2;
> + if (match(Op, m_AShr(m_ConstantInt(CI2), m_Value(A))) &&
> + (cast<BinaryOperator>(Op)->isExact())) {
> + Quotient = CI2->getValue().sdiv(CI->getValue());
> + return true;
> + }
> +
> + // Handle the case for lhsr.
> + if (match(Op, m_LShr(m_ConstantInt(CI2), m_Value(A))) &&
> + (cast<BinaryOperator>(Op)->isExact())) {
> + Quotient = CI2->getValue().udiv(CI->getValue());
> + return true;
> + }
> +
> + return false;
> +}
> +
> Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
> bool Changed = false;
> Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
> @@ -2443,13 +2469,10 @@
> // (icmp (ashr exact const2, A), const1) -> icmp A, Log2(const2/const1)
> // Cases where const1 doesn't divide const2 exactly or Quotient is not
> // exact of log2 are handled by SimplifyICmpInst call above where we
> - // return false.
> - // TODO: Handle this for lshr exact with udiv.
> + // return false. Similar for lshr.
> {
> - ConstantInt *CI2;
> - if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) &&
> - (cast<BinaryOperator>(Op0)->isExact())) {
> - APInt Quotient = CI2->getValue().sdiv(CI->getValue());
> + APInt Quotient;
> + if (checkShrExact(Op0, Quotient, CI, A)) {
> unsigned shift = Quotient.logBase2();
> return new ICmpInst(I.getPredicate(), A,
> ConstantInt::get(A->getType(), shift));
> Index: test/Transforms/InstCombine/icmp.ll
> ===================================================================
> --- test/Transforms/InstCombine/icmp.ll
> +++ test/Transforms/InstCombine/icmp.ll
> @@ -1390,3 +1390,11 @@
> %cmp = icmp eq i32 %shr, -15
> ret i1 %cmp
> }
> +
> +; CHECK-LABEL: @exact_lhsr
> +; CHECK-NEXT: icmp eq i32 %a, 3
> +define i1 @exact_lhsr(i32 %a) {
> + %shr = lshr exact i32 80, %a
> + %cmp = icmp eq i32 %shr, 10
> + ret i1 %cmp
> +}
More information about the llvm-commits
mailing list