[llvm] r175270 - Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2

Benjamin Kramer benny.kra at gmail.com
Sat Mar 9 02:08:07 PST 2013


On 15.02.2013, at 15:35, Arnaud A. de Grandmaison <arnaud.adegm at gmail.com> wrote:

> Author: aadg
> Date: Fri Feb 15 08:35:47 2013
> New Revision: 175270
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=175270&view=rev
> Log:
> Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2

It says legal types, but the code never actually checks for legality. Combined with the not checking for multiple uses on the shift you're introducing potentially expensive operations here.

The attached test case (extracted from scimark) shows a case where your patch adds a trunc to i61.

- Ben
-------------- next part --------------
A non-text attachment was scrubbed...
Name: measure.c
Type: application/octet-stream
Size: 831 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130309/0b1cccca/attachment.obj>
-------------- next part --------------

> 
> It enables to work with a smaller constant, which is target friendly for those which can compare to immediates.
> It also avoids inserting a shift in favor of a trunc, which can be free on some targets.
> 
> This used to work until LLVM-3.1, but regressed with the 3.2 release.
> 
> Modified:
>    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
>    llvm/trunk/test/Transforms/InstCombine/exact.ll
>    llvm/trunk/test/Transforms/InstCombine/icmp.ll
> 
> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=175270&r1=175269&r2=175270&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Fri Feb 15 08:35:47 2013
> @@ -1331,6 +1331,25 @@ Instruction *InstCombiner::visitICmpInst
>       return new ICmpInst(TrueIfSigned ? ICmpInst::ICMP_NE : ICmpInst::ICMP_EQ,
>                           And, Constant::getNullValue(And->getType()));
>     }
> +
> +    // Transform (icmp pred iM (shl iM %v, N), CI)
> +    // -> (icmp pred i(M-N) (trunc %v iM to i(N-N)), (trunc (CI>>N))
> +    // Transform the shl to a trunc if (trunc (CI>>N)) has no loss.
> +    // This enables to get rid of the shift in favor of a trunc which can be
> +    // free on the target. It has the additional benefit of comparing to a
> +    // smaller constant, which will be target friendly.
> +    unsigned Amt = ShAmt->getLimitedValue(TypeBits-1);
> +    if (Amt != 0 && RHSV.countTrailingZeros() >= Amt) {
> +      Type *NTy = IntegerType::get(ICI.getContext(), TypeBits - Amt);
> +      Constant *NCI = ConstantExpr::getTrunc(
> +                        ConstantExpr::getAShr(RHS,
> +                          ConstantInt::get(RHS->getType(), Amt)),
> +                        NTy);
> +      return new ICmpInst(ICI.getPredicate(),
> +                          Builder->CreateTrunc(LHSI->getOperand(0), NTy),
> +                          ConstantExpr::getTrunc(NCI, NTy));
> +    }
> +
>     break;
>   }
> 
> 
> Modified: llvm/trunk/test/Transforms/InstCombine/exact.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/exact.ll?rev=175270&r1=175269&r2=175270&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/exact.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/exact.ll Fri Feb 15 08:35:47 2013
> @@ -99,9 +99,9 @@ define i1 @ashr_icmp2(i64 %X) nounwind {
> ; PR9998
> ; Make sure we don't transform the ashr here into an sdiv
> ; CHECK: @pr9998
> -; CHECK: = and i32 %V, 1
> -; CHECK: %Z = icmp ne
> -; CHECK: ret i1 %Z
> +; CHECK:      [[BIT:%[A-Za-z0-9.]+]] = and i32 %V, 1
> +; CHECK-NEXT: [[CMP:%[A-Za-z0-9.]+]] = icmp ne i32 [[BIT]], 0
> +; CHECK-NEXT: ret i1 [[CMP]]
> define i1 @pr9998(i32 %V) nounwind {
> entry:
>   %W = shl i32 %V, 31
> @@ -112,6 +112,7 @@ entry:
> }
> 
> 
> +
> ; CHECK: @udiv_icmp1
> ; CHECK: icmp ne i64 %X, 0
> define i1 @udiv_icmp1(i64 %X) nounwind {
> 
> Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=175270&r1=175269&r2=175270&view=diff
> ==============================================================================
> --- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Fri Feb 15 08:35:47 2013
> @@ -706,3 +706,41 @@ define i1 @test69(i32 %c) nounwind uwtab
>   %3 = or i1 %1, %2
>   ret i1 %3
> }
> +
> +; CHECK: @icmp_sext16trunc
> +; CHECK-NEXT: %1 = trunc i32 %x to i16
> +; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
> +define i1 @icmp_sext16trunc(i32 %x) {
> +  %trunc = trunc i32 %x to i16
> +  %sext = sext i16 %trunc to i32
> +  %cmp = icmp slt i32 %sext, 36
> +  ret i1 %cmp
> +}
> +
> +; CHECK: @icmp_sext8trunc
> +; CHECK-NEXT: %1 = trunc i32 %x to i8
> +; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
> +define i1 @icmp_sext8trunc(i32 %x) {
> +  %trunc = trunc i32 %x to i8
> +  %sext = sext i8 %trunc to i32
> +  %cmp = icmp slt i32 %sext, 36
> +  ret i1 %cmp
> +}
> +
> +; CHECK: @icmp_shl16
> +; CHECK-NEXT: %1 = trunc i32 %x to i16
> +; CHECK-NEXT: %cmp = icmp slt i16 %1, 36
> +define i1 @icmp_shl16(i32 %x) {
> +  %shl = shl i32 %x, 16
> +  %cmp = icmp slt i32 %shl, 2359296
> +  ret i1 %cmp
> +}
> +
> +; CHECK: @icmp_shl24
> +; CHECK-NEXT: %1 = trunc i32 %x to i8
> +; CHECK-NEXT: %cmp = icmp slt i8 %1, 36
> +define i1 @icmp_shl24(i32 %x) {
> +  %shl = shl i32 %x, 24
> +  %cmp = icmp slt i32 %shl, 603979776
> +  ret i1 %cmp
> +}
> 
> 
> _______________________________________________
> 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