diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 7bbdd450f11..3fa0aba0129 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2580,10 +2580,32 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { } } + // Transform (zext A) == (B & (1< A == (trunc B) + ConstantInt *Cst1; + if (Op0->hasOneUse() && + match(Op0, m_ZExt(m_Value(A))) && + match(Op1, m_And(m_Value(B), m_ConstantInt(Cst1)))) { + APInt Pow2 = Cst1->getValue() + 1; + if (Pow2.isPowerOf2() && isa(A->getType()) && + Pow2.logBase2() == cast(A->getType())->getBitWidth()) + return new ICmpInst(I.getPredicate(), A, + Builder->CreateTrunc(B, A->getType())); + } + + // Transform (B & (1< A == (trunc B) + if (Op1->hasOneUse() && + match(Op0, m_And(m_Value(B), m_ConstantInt(Cst1))) && + match(Op1, m_ZExt(m_Value(A)))) { + APInt Pow2 = Cst1->getValue() + 1; + if (Pow2.isPowerOf2() && isa(A->getType()) && + Pow2.logBase2() == cast(A->getType())->getBitWidth()) + return new ICmpInst(I.getPredicate(), A, + Builder->CreateTrunc(B, A->getType())); + } + // Transform "icmp eq (trunc (lshr(X, cst1)), cst" to // "icmp (and X, mask), cst" uint64_t ShAmt = 0; - ConstantInt *Cst1; if (Op0->hasOneUse() && match(Op0, m_Trunc(m_OneUse(m_LShr(m_Value(A), m_ConstantInt(ShAmt))))) && diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index a9ae221d8f9..eaff87d695e 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -637,3 +637,25 @@ define i1 @test62(i8* %a) { ; CHECK: @test62 ; CHECK-NEXT: ret i1 true } + +define i1 @test63(i8 %a, i32 %b) nounwind { + %z = zext i8 %a to i32 + %t = and i32 %b, 255 + %c = icmp eq i32 %z, %t + ret i1 %c +; CHECK: @test63 +; CHECK-NEXT: %1 = trunc i32 %b to i8 +; CHECK-NEXT: %c = icmp eq i8 %1, %a +; CHECK-NEXT: ret i1 %c +} + +define i1 @test64(i8 %a, i32 %b) nounwind { + %t = and i32 %b, 255 + %z = zext i8 %a to i32 + %c = icmp eq i32 %t, %z + ret i1 %c +; CHECK: @test64 +; CHECK-NEXT: %1 = trunc i32 %b to i8 +; CHECK-NEXT: %c = icmp eq i8 %1, %a +; CHECK-NEXT: ret i1 %c +}