[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