[llvm] r213678 - This patch implements optimization as mentioned in PR19753: Optimize comparisons with "ashr/lshr exact" of a constanst.

Sean Silva chisophugis at gmail.com
Fri Oct 17 16:26:29 PDT 2014


Sorry for the necro-post, but did this get verified with an SMT solver?

Sanjay (CC'd) even provided links to example code for using an SMT solver
to verify it in http://llvm.org/bugs/show_bug.cgi?id=19958#c9

-- Sean Silva

On Tue, Jul 22, 2014 at 12:19 PM, Suyog Sarda <suyog.sarda at samsung.com>
wrote:

> Author: suyog
> Date: Tue Jul 22 14:19:36 2014
> New Revision: 213678
>
> URL: http://llvm.org/viewvc/llvm-project?rev=213678&view=rev
> Log:
> This patch implements optimization as mentioned in PR19753: Optimize
> comparisons with "ashr/lshr exact" of a constanst.
> It handles the errors which were seen in PR19958 where wrong code was
> being emitted due to earlier patch.
> Added code for lshr as well as non-exact right shifts.
>
> It implements :
> (icmp eq/ne (ashr/lshr const2, A), const1)" ->
> (icmp eq/ne A, Log2(const2/const1)) ->
> (icmp eq/ne A, Log2(const2) - Log2(const1))
>
> Differential Revision: http://reviews.llvm.org/D4068
>
>
> Added:
>     llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll
> Modified:
>     llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
>     llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombine.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombine.h?rev=213678&r1=213677&r2=213678&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombine.h (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombine.h Tue Jul 22
> 14:19:36 2014
> @@ -172,6 +172,8 @@ public:
>                                ConstantInt *DivRHS);
>    Instruction *FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *DivI,
>                                ConstantInt *DivRHS);
> +  Instruction *FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
> +                                 ConstantInt *CI1, ConstantInt *CI2);
>    Instruction *FoldICmpAddOpCst(Instruction &ICI, Value *X, ConstantInt
> *CI,
>                                  ICmpInst::Predicate Pred);
>    Instruction *FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
>
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=213678&r1=213677&r2=213678&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
> (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue Jul
> 22 14:19:36 2014
> @@ -1044,6 +1044,90 @@ Instruction *InstCombiner::FoldICmpShrCs
>    return nullptr;
>  }
>
> +/// FoldICmpCstShrCst - Handle "(icmp eq/ne (ashr/lshr const2, A),
> const1)" ->
> +/// (icmp eq/ne A, Log2(const2/const1)) ->
> +/// (icmp eq/ne A, Log2(const2) - Log2(const1)).
> +Instruction *InstCombiner::FoldICmpCstShrCst(ICmpInst &I, Value *Op,
> Value *A,
> +                                             ConstantInt *CI1,
> +                                             ConstantInt *CI2) {
> +  assert(I.isEquality() && "Cannot fold icmp gt/lt");
> +
> +  auto getConstant = [&I, this](bool IsTrue) {
> +    if (I.getPredicate() == I.ICMP_NE)
> +      IsTrue = !IsTrue;
> +    return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), IsTrue));
> +  };
> +
> +  auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
> +    if (I.getPredicate() == I.ICMP_NE)
> +      Pred = CmpInst::getInversePredicate(Pred);
> +    return new ICmpInst(Pred, LHS, RHS);
> +  };
> +
> +  APInt AP1 = CI1->getValue();
> +  APInt AP2 = CI2->getValue();
> +
> +  if (!AP1) {
> +    if (!AP2) {
> +      // Both Constants are 0.
> +      return getConstant(true);
> +    }
> +
> +    if (cast<BinaryOperator>(Op)->isExact())
> +      return getConstant(false);
> +
> +    if (AP2.isNegative()) {
> +      // MSB is set, so a lshr with a large enough 'A' would be undefined.
> +      return getConstant(false);
> +    }
> +
> +    // 'A' must be large enough to shift out the highest set bit.
> +    return getICmp(I.ICMP_UGT, A,
> +                   ConstantInt::get(A->getType(), AP2.logBase2()));
> +  }
> +
> +  if (!AP2) {
> +    // Shifting 0 by any value gives 0.
> +    return getConstant(false);
> +  }
> +
> +  bool IsAShr = isa<AShrOperator>(Op);
> +  if (AP1 == AP2) {
> +    if (AP1.isAllOnesValue() && IsAShr) {
> +      // Arithmatic shift of -1 is always -1.
> +      return getConstant(true);
> +    }
> +    return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType()));
> +  }
> +
> +  if (IsAShr) {
> +    if (AP1.isNegative() != AP2.isNegative()) {
> +      // Arithmetic shift will never change the sign.
> +      return getConstant(false);
> +    }
> +    // Both the constants are negative, take their positive to calculate
> +    // log.
> +    if (AP1.isNegative()) {
> +      AP1 = -AP1;
> +      AP2 = -AP2;
> +    }
> +  }
> +
> +  if (AP1.ugt(AP2)) {
> +    // Right-shifting will not increase the value.
> +    return getConstant(false);
> +  }
> +
> +  // Get the distance between the highest bit that's set.
> +  int Shift = AP2.logBase2() - AP1.logBase2();
> +
> +  // Use lshr here, since we've canonicalized to +ve numbers.
> +  if (AP1 == AP2.lshr(Shift))
> +    return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
> +
> +  // Shifting const2 will never be equal to const1.
> +  return getConstant(false);
> +}
>
>  /// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)".
>  ///
> @@ -2469,6 +2553,15 @@ Instruction *InstCombiner::visitICmpInst
>                            Builder->getInt(CI->getValue()-1));
>      }
>
> +    // (icmp eq/ne (ashr/lshr const2, A), const1)
> +    if (I.isEquality()) {
> +      ConstantInt *CI2;
> +      if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) ||
> +          match(Op0, m_LShr(m_ConstantInt(CI2), m_Value(A)))) {
> +        return FoldICmpCstShrCst(I, Op0, A, CI, CI2);
> +      }
> +    }
> +
>      // If this comparison is a normal comparison, it demands all
>      // bits, if it is a sign bit comparison, it only demands the sign bit.
>      bool UnusedBit;
>
> Added: llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll?rev=213678&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll (added)
> +++ llvm/trunk/test/Transforms/InstCombine/icmp-shr.ll Tue Jul 22 14:19:36
> 2014
> @@ -0,0 +1,677 @@
> +; RUN: opt < %s -instcombine -S | FileCheck %s
> +
> +target datalayout =
> "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
> +
> +; CHECK-LABEL: @exact_lshr_eq_both_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_lshr_eq_both_zero(i8 %a) {
> + %shr = lshr exact i8 0, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_both_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_eq_both_zero(i8 %a) {
> + %shr = ashr exact i8 0, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_both_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_lshr_eq_both_zero(i8 %a) {
> + %shr = lshr i8 0, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_both_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_ashr_eq_both_zero(i8 %a) {
> + %shr = ashr i8 0, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_both_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_lshr_ne_both_zero(i8 %a) {
> + %shr = lshr exact i8 0, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_both_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_ne_both_zero(i8 %a) {
> + %shr = ashr exact i8 0, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_both_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_lshr_ne_both_zero(i8 %a) {
> + %shr = lshr i8 0, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_both_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_ashr_ne_both_zero(i8 %a) {
> + %shr = ashr i8 0, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_last_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_lshr_eq_last_zero(i8 %a) {
> + %shr = lshr exact i8 128, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_last_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_eq_last_zero(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_last_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_lshr_ne_last_zero(i8 %a) {
> + %shr = lshr exact i8 128, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_last_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_ne_last_zero(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_last_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_lshr_eq_last_zero(i8 %a) {
> + %shr = lshr i8 128, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_last_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_ashr_eq_last_zero(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_last_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_lshr_ne_last_zero(i8 %a) {
> + %shr = lshr i8 128, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_last_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_ashr_ne_last_zero(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_eq_msb_low_last_zero
> +; CHECK-NEXT: icmp ugt i8 %a, 6
> +define i1 @lshr_eq_msb_low_last_zero(i8 %a) {
> + %shr = lshr i8 127, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_eq_msb_low_second_zero
> +; CHECK-NEXT: icmp ugt i8 %a, 6
> +define i1 @ashr_eq_msb_low_second_zero(i8 %a) {
> + %shr = ashr i8 127, %a
> + %cmp = icmp eq i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_ne_msb_low_last_zero
> +; CHECK-NEXT: icmp ult i8 %a, 7
> +define i1 @lshr_ne_msb_low_last_zero(i8 %a) {
> + %shr = lshr i8 127, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_ne_msb_low_second_zero
> +; CHECK-NEXT: icmp ult i8 %a, 7
> +define i1 @ashr_ne_msb_low_second_zero(i8 %a) {
> + %shr = ashr i8 127, %a
> + %cmp = icmp ne i8 %shr, 0
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_eq_first_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @lshr_eq_first_zero(i8 %a) {
> + %shr = lshr i8 0, %a
> + %cmp = icmp eq i8 %shr, 2
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_eq_first_zero
> +; CHECK-NEXT: ret i1 false
> +define i1 @ashr_eq_first_zero(i8 %a) {
> + %shr = ashr i8 0, %a
> + %cmp = icmp eq i8 %shr, 2
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_ne_first_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @lshr_ne_first_zero(i8 %a) {
> + %shr = lshr i8 0, %a
> + %cmp = icmp ne i8 %shr, 2
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_ne_first_zero
> +; CHECK-NEXT: ret i1 true
> +define i1 @ashr_ne_first_zero(i8 %a) {
> + %shr = ashr i8 0, %a
> + %cmp = icmp ne i8 %shr, 2
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_eq_both_minus1
> +; CHECK-NEXT: ret i1 true
> +define i1 @ashr_eq_both_minus1(i8 %a) {
> + %shr = ashr i8 -1, %a
> + %cmp = icmp eq i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_ne_both_minus1
> +; CHECK-NEXT: ret i1 false
> +define i1 @ashr_ne_both_minus1(i8 %a) {
> + %shr = ashr i8 -1, %a
> + %cmp = icmp ne i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_both_minus1
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_eq_both_minus1(i8 %a) {
> + %shr = ashr exact i8 -1, %a
> + %cmp = icmp eq i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_both_minus1
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_ne_both_minus1(i8 %a) {
> + %shr = ashr exact i8 -1, %a
> + %cmp = icmp ne i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_eq_both_equal
> +; CHECK-NEXT: icmp eq i8 %a, 0
> +define i1 @ashr_eq_both_equal(i8 %a) {
> + %shr = ashr i8 128, %a
> + %cmp = icmp eq i8 %shr, 128
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_ne_both_equal
> +; CHECK-NEXT: icmp ne i8 %a, 0
> +define i1 @ashr_ne_both_equal(i8 %a) {
> + %shr = ashr i8 128, %a
> + %cmp = icmp ne i8 %shr, 128
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_eq_both_equal
> +; CHECK-NEXT: icmp eq i8 %a, 0
> +define i1 @lshr_eq_both_equal(i8 %a) {
> + %shr = lshr i8 127, %a
> + %cmp = icmp eq i8 %shr, 127
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_ne_both_equal
> +; CHECK-NEXT: icmp ne i8 %a, 0
> +define i1 @lshr_ne_both_equal(i8 %a) {
> + %shr = lshr i8 127, %a
> + %cmp = icmp ne i8 %shr, 127
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_both_equal
> +; CHECK-NEXT: icmp eq i8 %a, 0
> +define i1 @exact_ashr_eq_both_equal(i8 %a) {
> + %shr = ashr exact i8 128, %a
> + %cmp = icmp eq i8 %shr, 128
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_both_equal
> +; CHECK-NEXT: icmp ne i8 %a, 0
> +define i1 @exact_ashr_ne_both_equal(i8 %a) {
> + %shr = ashr exact i8 128, %a
> + %cmp = icmp ne i8 %shr, 128
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_both_equal
> +; CHECK-NEXT: icmp eq i8 %a, 0
> +define i1 @exact_lshr_eq_both_equal(i8 %a) {
> + %shr = lshr exact i8 126, %a
> + %cmp = icmp eq i8 %shr, 126
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_both_equal
> +; CHECK-NEXT: icmp ne i8 %a, 0
> +define i1 @exact_lshr_ne_both_equal(i8 %a) {
> + %shr = lshr exact i8 126, %a
> + %cmp = icmp ne i8 %shr, 126
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_opposite_msb
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_eq_opposite_msb(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_eq_opposite_msb
> +; CHECK-NEXT: ret i1 false
> +define i1 @ashr_eq_opposite_msb(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_opposite_msb
> +; CHECK-NEXT: icmp eq i8 %a, 7
> +define i1 @exact_lshr_eq_opposite_msb(i8 %a) {
> + %shr = lshr exact i8 -128, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_eq_opposite_msb
> +; CHECK-NEXT: icmp eq i8 %a, 7
> +define i1 @lshr_eq_opposite_msb(i8 %a) {
> + %shr = lshr i8 -128, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_opposite_msb
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_ne_opposite_msb(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @ashr_ne_opposite_msb
> +; CHECK-NEXT: ret i1 true
> +define i1 @ashr_ne_opposite_msb(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_opposite_msb
> +; CHECK-NEXT: icmp ne i8 %a, 7
> +define i1 @exact_lshr_ne_opposite_msb(i8 %a) {
> + %shr = lshr exact i8 -128, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @lshr_ne_opposite_msb
> +; CHECK-NEXT: icmp ne i8 %a, 7
> +define i1 @lshr_ne_opposite_msb(i8 %a) {
> + %shr = lshr i8 -128, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_shift_gt
> +; CHECK-NEXT : ret i1 false
> +define i1 @exact_ashr_eq_shift_gt(i8 %a) {
> + %shr = ashr exact i8 -2, %a
> + %cmp = icmp eq i8 %shr, -8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_shift_gt
> +; CHECK-NEXT : ret i1 true
> +define i1 @exact_ashr_ne_shift_gt(i8 %a) {
> + %shr = ashr exact i8 -2, %a
> + %cmp = icmp ne i8 %shr, -8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_shift_gt
> +; CHECK-NEXT : ret i1 false
> +define i1 @nonexact_ashr_eq_shift_gt(i8 %a) {
> + %shr = ashr i8 -2, %a
> + %cmp = icmp eq i8 %shr, -8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_shift_gt
> +; CHECK-NEXT : ret i1 true
> +define i1 @nonexact_ashr_ne_shift_gt(i8 %a) {
> + %shr = ashr i8 -2, %a
> + %cmp = icmp ne i8 %shr, -8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_shift_gt
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_lshr_eq_shift_gt(i8 %a) {
> + %shr = lshr exact i8 2, %a
> + %cmp = icmp eq i8 %shr, 8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_shift_gt
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_lshr_ne_shift_gt(i8 %a) {
> + %shr = lshr exact i8 2, %a
> + %cmp = icmp ne i8 %shr, 8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_shift_gt
> +; CHECK-NEXT : ret i1 false
> +define i1 @nonexact_lshr_eq_shift_gt(i8 %a) {
> + %shr = lshr i8 2, %a
> + %cmp = icmp eq i8 %shr, 8
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_shift_gt
> +; CHECK-NEXT : ret i1 true
> +define i1 @nonexact_lshr_ne_shift_gt(i8 %a) {
> + %shr = ashr i8 2, %a
> + %cmp = icmp ne i8 %shr, 8
> + ret i1 %cmp
> +}
> +
> +
> +
> +; CHECK-LABEL: @exact_ashr_eq
> +; CHECK-NEXT: icmp eq i8 %a, 7
> +define i1 @exact_ashr_eq(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp eq i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne
> +; CHECK-NEXT: icmp ne i8 %a, 7
> +define i1 @exact_ashr_ne(i8 %a) {
> + %shr = ashr exact i8 -128, %a
> + %cmp = icmp ne i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq
> +; CHECK-NEXT: icmp eq i8 %a, 2
> +define i1 @exact_lshr_eq(i8 %a) {
> + %shr = lshr exact i8 4, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne
> +; CHECK-NEXT: icmp ne i8 %a, 2
> +define i1 @exact_lshr_ne(i8 %a) {
> + %shr = lshr exact i8 4, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq
> +; CHECK-NEXT: icmp eq i8 %a, 7
> +define i1 @nonexact_ashr_eq(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp eq i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne
> +; CHECK-NEXT: icmp ne i8 %a, 7
> +define i1 @nonexact_ashr_ne(i8 %a) {
> + %shr = ashr i8 -128, %a
> + %cmp = icmp ne i8 %shr, -1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq
> +; CHECK-NEXT: icmp eq i8 %a, 2
> +define i1 @nonexact_lshr_eq(i8 %a) {
> + %shr = lshr i8 4, %a
> + %cmp = icmp eq i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne
> +; CHECK-NEXT: icmp ne i8 %a, 2
> +define i1 @nonexact_lshr_ne(i8 %a) {
> + %shr = lshr i8 4, %a
> + %cmp = icmp ne i8 %shr, 1
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_exactdiv
> +; CHECK-NEXT: icmp eq i8 %a, 4
> +define i1 @exact_lshr_eq_exactdiv(i8 %a) {
> + %shr = lshr exact i8 80, %a
> + %cmp = icmp eq i8 %shr, 5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_exactdiv
> +; CHECK-NEXT: icmp ne i8 %a, 4
> +define i1 @exact_lshr_ne_exactdiv(i8 %a) {
> + %shr = lshr exact i8 80, %a
> + %cmp = icmp ne i8 %shr, 5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_exactdiv
> +; CHECK-NEXT: icmp eq i8 %a, 4
> +define i1 @nonexact_lshr_eq_exactdiv(i8 %a) {
> + %shr = lshr i8 80, %a
> + %cmp = icmp eq i8 %shr, 5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_exactdiv
> +; CHECK-NEXT: icmp ne i8 %a, 4
> +define i1 @nonexact_lshr_ne_exactdiv(i8 %a) {
> + %shr = lshr i8 80, %a
> + %cmp = icmp ne i8 %shr, 5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_exactdiv
> +; CHECK-NEXT: icmp eq i8 %a, 4
> +define i1 @exact_ashr_eq_exactdiv(i8 %a) {
> + %shr = ashr exact i8 -80, %a
> + %cmp = icmp eq i8 %shr, -5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_exactdiv
> +; CHECK-NEXT: icmp ne i8 %a, 4
> +define i1 @exact_ashr_ne_exactdiv(i8 %a) {
> + %shr = ashr exact i8 -80, %a
> + %cmp = icmp ne i8 %shr, -5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_exactdiv
> +; CHECK-NEXT: icmp eq i8 %a, 4
> +define i1 @nonexact_ashr_eq_exactdiv(i8 %a) {
> + %shr = ashr i8 -80, %a
> + %cmp = icmp eq i8 %shr, -5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_exactdiv
> +; CHECK-NEXT: icmp ne i8 %a, 4
> +define i1 @nonexact_ashr_ne_exactdiv(i8 %a) {
> + %shr = ashr i8 -80, %a
> + %cmp = icmp ne i8 %shr, -5
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_noexactdiv
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_lshr_eq_noexactdiv(i8 %a) {
> + %shr = lshr exact i8 80, %a
> + %cmp = icmp eq i8 %shr, 31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_noexactdiv
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_lshr_ne_noexactdiv(i8 %a) {
> + %shr = lshr exact i8 80, %a
> + %cmp = icmp ne i8 %shr, 31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_noexactdiv
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_lshr_eq_noexactdiv(i8 %a) {
> + %shr = lshr i8 80, %a
> + %cmp = icmp eq i8 %shr, 31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_noexactdiv
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_lshr_ne_noexactdiv(i8 %a) {
> + %shr = lshr i8 80, %a
> + %cmp = icmp ne i8 %shr, 31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_noexactdiv
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_eq_noexactdiv(i8 %a) {
> + %shr = ashr exact i8 -80, %a
> + %cmp = icmp eq i8 %shr, -31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_noexactdiv
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_ne_noexactdiv(i8 %a) {
> + %shr = ashr exact i8 -80, %a
> + %cmp = icmp ne i8 %shr, -31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_noexactdiv
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_ashr_eq_noexactdiv(i8 %a) {
> + %shr = ashr i8 -80, %a
> + %cmp = icmp eq i8 %shr, -31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_noexactdiv
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_ashr_ne_noexactdiv(i8 %a) {
> + %shr = ashr i8 -80, %a
> + %cmp = icmp ne i8 %shr, -31
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_eq_noexactlog
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_lshr_eq_noexactlog(i8 %a) {
> + %shr = lshr exact i8 90, %a
> + %cmp = icmp eq i8 %shr, 30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_lshr_ne_noexactlog
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_lshr_ne_noexactlog(i8 %a) {
> + %shr = lshr exact i8 90, %a
> + %cmp = icmp ne i8 %shr, 30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_eq_noexactlog
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_lshr_eq_noexactlog(i8 %a) {
> + %shr = lshr i8 90, %a
> + %cmp = icmp eq i8 %shr, 30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_lshr_ne_noexactlog
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_lshr_ne_noexactlog(i8 %a) {
> + %shr = lshr i8 90, %a
> + %cmp = icmp ne i8 %shr, 30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_eq_noexactlog
> +; CHECK-NEXT: ret i1 false
> +define i1 @exact_ashr_eq_noexactlog(i8 %a) {
> + %shr = ashr exact i8 -90, %a
> + %cmp = icmp eq i8 %shr, -30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @exact_ashr_ne_noexactlog
> +; CHECK-NEXT: ret i1 true
> +define i1 @exact_ashr_ne_noexactlog(i8 %a) {
> + %shr = ashr exact i8 -90, %a
> + %cmp = icmp ne i8 %shr, -30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_eq_noexactlog
> +; CHECK-NEXT: ret i1 false
> +define i1 @nonexact_ashr_eq_noexactlog(i8 %a) {
> + %shr = ashr i8 -90, %a
> + %cmp = icmp eq i8 %shr, -30
> + ret i1 %cmp
> +}
> +
> +; CHECK-LABEL: @nonexact_ashr_ne_noexactlog
> +; CHECK-NEXT: ret i1 true
> +define i1 @nonexact_ashr_ne_noexactlog(i8 %a) {
> + %shr = ashr i8 -90, %a
> + %cmp = icmp ne i8 %shr, -30
> + ret i1 %cmp
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141017/0a4d043e/attachment.html>


More information about the llvm-commits mailing list