From: Sanjay Patel Date: Tue, 11 Sep 2018 22:00:15 +0000 (+0000) Subject: [InstCombine] add folds for icmp with xor mask constant X-Git-Tag: llvmorg-8.0.0-rc1~8942 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=26725bdc508f0c011e39f7ef0125e961d2ad76ed;p=platform%2Fupstream%2Fllvm.git [InstCombine] add folds for icmp with xor mask constant These are the folds in Alive; Name: xor_ult Pre: isPowerOf2(-C1) %xor = xor i8 %x, C1 %r = icmp ult i8 %xor, C1 => %r = icmp ugt i8 %x, ~C1 Name: xor_ugt Pre: isPowerOf2(C1+1) %xor = xor i8 %x, C1 %r = icmp ugt i8 %xor, C1 => %r = icmp ugt i8 %x, C1 https://rise4fun.com/Alive/Vty The ugt case in its simplest form was already handled by DemandedBits, but that's not ideal as shown in the multi-use test. I'm not sure if these are all of the symmetrical folds, but I adjusted the existing code for one of the folds to try to show the similarities. There's no obvious connection, but this is another preliminary step for PR14613... https://bugs.llvm.org/show_bug.cgi?id=14613 llvm-svn: 341997 --- diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 4b58914..e8e9e86 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1499,16 +1499,25 @@ Instruction *InstCombiner::foldICmpXorConstant(ICmpInst &Cmp, } } - // (icmp ugt (xor X, C), ~C) -> (icmp ult X, C) - // iff -C is a power of 2 - if (Pred == ICmpInst::ICMP_UGT && *XorC == ~C && (C + 1).isPowerOf2()) - return new ICmpInst(ICmpInst::ICMP_ULT, X, Y); - - // (icmp ult (xor X, C), -C) -> (icmp uge X, C) - // iff -C is a power of 2 - if (Pred == ICmpInst::ICMP_ULT && *XorC == -C && C.isPowerOf2()) - return new ICmpInst(ICmpInst::ICMP_UGE, X, Y); - + // Mask constant magic can eliminate an 'xor' with unsigned compares. + if (Pred == ICmpInst::ICMP_UGT) { + // (xor X, ~C) >u C --> X u C --> X >u C (when C+1 is a power of 2) + if (*XorC == C && (C + 1).isPowerOf2()) + return new ICmpInst(ICmpInst::ICMP_UGT, X, Y); + } + if (Pred == ICmpInst::ICMP_ULT) { + // (xor X, -C) X >u ~C (when C is a power of 2) + if (*XorC == -C && C.isPowerOf2()) + return new ICmpInst(ICmpInst::ICMP_UGT, X, + ConstantInt::get(X->getType(), ~C)); + // (xor X, C) X >u ~C (when -C is a power of 2) + if (*XorC == C && (-C).isPowerOf2()) + return new ICmpInst(ICmpInst::ICMP_UGT, X, + ConstantInt::get(X->getType(), ~C)); + } return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 546ed9b..623f401 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -2229,8 +2229,7 @@ define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) { define <2 x i1> @xor_ult(<2 x i8> %x) { ; CHECK-LABEL: @xor_ult( -; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i8> [[XOR]], +; CHECK-NEXT: [[R:%.*]] = icmp ugt <2 x i8> [[X:%.*]], ; CHECK-NEXT: ret <2 x i1> [[R]] ; %xor = xor <2 x i8> %x, @@ -2242,7 +2241,7 @@ define i1 @xor_ult_extra_use(i8 %x, i8* %p) { ; CHECK-LABEL: @xor_ult_extra_use( ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], -32 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 -; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[XOR]], -32 +; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 31 ; CHECK-NEXT: ret i1 [[R]] ; %xor = xor i8 %x, -32 @@ -2265,7 +2264,7 @@ define i1 @xor_ugt_extra_use(i8 %x, i8* %p) { ; CHECK-LABEL: @xor_ugt_extra_use( ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], 63 ; CHECK-NEXT: store i8 [[XOR]], i8* [[P:%.*]], align 1 -; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[XOR]], 63 +; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X]], 63 ; CHECK-NEXT: ret i1 [[R]] ; %xor = xor i8 %x, 63