[llvm-commits] [llvm] r131860 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp test/Transforms/InstCombine/div.ll

Duncan Sands baldrick at free.fr
Sun May 22 12:17:32 PDT 2011


Hi Chris,

> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Sun May 22 13:18:41 2011
> @@ -19,6 +19,31 @@
>   using namespace llvm;
>   using namespace PatternMatch;
>
> +
> +/// simplifyValueKnownNonZero - The specific integer value is used in a context
> +/// where it is known to be non-zero.  If this allows us to simplify the
> +/// computation, do so and return the new operand, otherwise return null.
> +static Value *simplifyValueKnownNonZero(Value *V, InstCombiner&IC) {
> +  // If V has multiple uses, then we would have to do more analysis to determine
> +  // if this is safe.  For example, the use could be in dynamically unreached
> +  // code.
> +  if (!V->hasOneUse()) return 0;
> +
> +  // ((1<<  A)>>u B) -->  (1<<  (A-B))
> +  // Because V cannot be zero, we know that B is less than A.
> +  Value *A = 0, *B = 0; ConstantInt *One = 0;
> +  if (match(V, m_LShr(m_OneUse(m_Shl(m_ConstantInt(One), m_Value(A))),
> +                      m_Value(B)))&&
> +      // The "1" can be any value known to be a power of 2.
> +      One->getValue().isPowerOf2()) {

ValueTracking has a isPowerOfTwo method which can also tell that some
non-constant expressions are powers of two.

Ciao, Duncan.

> +    A = IC.Builder->CreateSub(A, B, "tmp");
> +    return IC.Builder->CreateShl(One, A);
> +  }
> +
> +  return 0;
> +}
> +
> +
>   /// MultiplyOverflows - True if the multiply can not be expressed in an int
>   /// this size.
>   static bool MultiplyOverflows(ConstantInt *C1, ConstantInt *C2, bool sign) {
> @@ -293,6 +318,12 @@
>   Instruction *InstCombiner::commonIDivTransforms(BinaryOperator&I) {
>     Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
>
> +  // The RHS is known non-zero.
> +  if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this)) {
> +    I.setOperand(1, V);
> +    return&I;
> +  }
> +
>     // Handle cases involving: [su]div X, (select Cond, Y, Z)
>     // This does not apply for fdiv.
>     if (isa<SelectInst>(Op1)&&  SimplifyDivRemOfSelect(I))
> @@ -499,6 +530,12 @@
>   Instruction *InstCombiner::commonIRemTransforms(BinaryOperator&I) {
>     Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
>
> +  // The RHS is known non-zero.
> +  if (Value *V = simplifyValueKnownNonZero(I.getOperand(1), *this)) {
> +    I.setOperand(1, V);
> +    return&I;
> +  }
> +
>     // Handle cases involving: rem X, (select Cond, Y, Z)
>     if (isa<SelectInst>(Op1)&&  SimplifyDivRemOfSelect(I))
>       return&I;
>
> Modified: llvm/trunk/test/Transforms/InstCombine/div.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/div.ll?rev=131860&r1=131859&r2=131860&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/div.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/div.ll Sun May 22 13:18:41 2011
> @@ -118,3 +118,17 @@
>   ; CHECK: @test14
>   ; CHECK-NEXT: ret i32 0
>   }
> +
> +; PR9814
> +define i32 @test15(i32 %a, i32 %b) nounwind {
> +  %shl = shl i32 1, %b
> +  %div = lshr i32 %shl, 2
> +  %div2 = udiv i32 %a, %div
> +  ret i32 %div2
> +; CHECK: @test15
> +; CHECK-NEXT: add i32 %b, -2
> +; CHECK-NEXT: lshr i32 %a,
> +; CHECK-NEXT: ret i32
> +}
> +
> +
>
>
> _______________________________________________
> 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