[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