From 26a5db075f0b48f6e539ebff21c060264935ea01 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 2 Dec 2015 16:15:07 +0000 Subject: [PATCH] Do (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 rather than (A == C1 || A == C2) -> (A | (C1 ^ C2)) == C2 when C1 ^ C2 is a power of 2. Differential Revision: http://reviews.llvm.org/D14223 Patch by Amaury SECHET! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254518 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 8 ++++---- test/Transforms/InstCombine/icmp.ll | 4 ++-- test/Transforms/InstCombine/load-cmp.ll | 4 ++-- test/Transforms/InstCombine/or.ll | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index f72089e6c8e..2bf6faa47b9 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1962,14 +1962,14 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, case ICmpInst::ICMP_EQ: if (LHS->getOperand(0) == RHS->getOperand(0)) { // if LHSCst and RHSCst differ only by one bit: - // (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 + // (A == C1 || A == C2) -> (A | (C1 ^ C2)) == C2 assert(LHSCst->getValue().ule(LHSCst->getValue())); APInt Xor = LHSCst->getValue() ^ RHSCst->getValue(); if (Xor.isPowerOf2()) { - Value *NegCst = Builder->getInt(~Xor); - Value *And = Builder->CreateAnd(LHS->getOperand(0), NegCst); - return Builder->CreateICmp(ICmpInst::ICMP_EQ, And, LHSCst); + Value *Cst = Builder->getInt(Xor); + Value *Or = Builder->CreateOr(LHS->getOperand(0), Cst); + return Builder->CreateICmp(ICmpInst::ICMP_EQ, Or, RHSCst); } } diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index a85bee5c2c9..7d6ec96b532 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -819,8 +819,8 @@ define i1 @test68(i32 %x) nounwind uwtable { ; PR14708 ; CHECK-LABEL: @test69( -; CHECK: %1 = and i32 %c, -33 -; CHECK: %2 = icmp eq i32 %1, 65 +; CHECK: %1 = or i32 %c, 32 +; CHECK: %2 = icmp eq i32 %1, 97 ; CHECK: ret i1 %2 define i1 @test69(i32 %c) nounwind uwtable { %1 = icmp eq i32 %c, 97 diff --git a/test/Transforms/InstCombine/load-cmp.ll b/test/Transforms/InstCombine/load-cmp.ll index 0bd9eb52191..fe1bf151753 100644 --- a/test/Transforms/InstCombine/load-cmp.ll +++ b/test/Transforms/InstCombine/load-cmp.ll @@ -148,8 +148,8 @@ define i1 @test8(i32 %X) { %S = icmp eq i16 %R, 0 ret i1 %S ; CHECK-LABEL: @test8( -; CHECK-NEXT: and i32 %X, -2 -; CHECK-NEXT: icmp eq i32 {{.*}}, 8 +; CHECK-NEXT: or i32 %X, 1 +; CHECK-NEXT: icmp eq i32 {{.*}}, 9 ; CHECK-NEXT: ret i1 } diff --git a/test/Transforms/InstCombine/or.ll b/test/Transforms/InstCombine/or.ll index b91a5954d97..a2bc4e7d983 100644 --- a/test/Transforms/InstCombine/or.ll +++ b/test/Transforms/InstCombine/or.ll @@ -182,7 +182,7 @@ define i1 @test19(i32 %A) { %D = or i1 %B, %C ret i1 %D ; CHECK-LABEL: @test19( -; CHECK: and i32 +; CHECK: or i32 ; CHECK: icmp eq ; CHECK: ret i1 } -- 2.34.1