From 7c5c9b39c91d5f53284011c0ddbf458d553740da Mon Sep 17 00:00:00 2001 From: "Arnaud A. de Grandmaison" Date: Fri, 15 Feb 2013 14:35:47 +0000 Subject: [PATCH] Teach InstCombine to work with smaller legal types in icmp (shl %v, C1), C2 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175270 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCompares.cpp | 19 ++++++++++ test/Transforms/InstCombine/exact.ll | 7 ++-- test/Transforms/InstCombine/icmp.ll | 38 +++++++++++++++++++ 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 40e559eda5e..2e7bd922a27 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1331,6 +1331,25 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, 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; } diff --git a/test/Transforms/InstCombine/exact.ll b/test/Transforms/InstCombine/exact.ll index 14741e3c1c3..88ca88c3b92 100644 --- a/test/Transforms/InstCombine/exact.ll +++ b/test/Transforms/InstCombine/exact.ll @@ -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 { diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 8fb6144c3f1..331eb3f21a9 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -706,3 +706,41 @@ define i1 @test69(i32 %c) nounwind uwtable { %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 +} -- 2.34.1