From: Benjamin Kramer Date: Sun, 12 Jun 2011 22:48:00 +0000 (+0000) Subject: InstCombine: Shrink ((zext X) & C1) == C2 to fold away the cast if the "zext" and... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ffd0ae64c497d13956d16526c46245bfbf48e91f;p=oota-llvm.git InstCombine: Shrink ((zext X) & C1) == C2 to fold away the cast if the "zext" and the "and" have one use. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132897 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 92cbc1b7f18..5ddf23ba8e1 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1097,7 +1097,23 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, ConstantExpr::getZExt(RHS, Cast->getSrcTy())); } } - + + // If the LHS is an AND of a zext, and we have an equality compare, we can + // shrink the and/compare to the smaller type, eliminating the cast. + if (ZExtInst *Cast = dyn_cast(LHSI->getOperand(0))) { + const IntegerType *Ty = cast(Cast->getSrcTy()); + // Make sure we don't compare the upper bits, SimplifyDemandedBits + // should fold the icmp to true/false in that case. + if (ICI.isEquality() && RHSV.getActiveBits() <= Ty->getBitWidth()) { + Value *NewAnd = + Builder->CreateAnd(Cast->getOperand(0), + ConstantExpr::getTrunc(AndCST, Ty)); + NewAnd->takeName(LHSI); + return new ICmpInst(ICI.getPredicate(), NewAnd, + ConstantExpr::getTrunc(RHS, Ty)); + } + } + // If this is: (X >> C1) & C2 != C3 (where any shift and any compare // could exist), turn it into (X & (C2 << C1)) != (C3 << C1). This // happens a LOT in code produced by the C front-end, for bitfield diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 1237adee74d..ecbba23091c 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -521,3 +521,13 @@ define i1 @test53(i32 %a, i32 %b) nounwind { %z = icmp eq i32 %x, %y ret i1 %z } + +; CHECK: @test54 +; CHECK-NEXT: %and = and i8 %a, -64 +; CHECK-NEXT icmp eq i8 %and, -128 +define i1 @test54(i8 %a) nounwind { + %ext = zext i8 %a to i32 + %and = and i32 %ext, 192 + %ret = icmp eq i32 %and, 128 + ret i1 %ret +}