From fecf0d7a0157011964b4f31a7a5374076b1b236c Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 9 Jul 2013 09:20:58 +0000 Subject: [PATCH] InstCombine: variations on 0xffffffff - x >= 4 The following transforms are valid if -C is a power of 2: (icmp ugt (xor X, C), ~C) -> (icmp ult X, C) (icmp ult (xor X, C), -C) -> (icmp uge X, C) These are nice, they get rid of the xor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185915 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineCompares.cpp | 12 ++++++++++++ test/Transforms/InstCombine/icmp.ll | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index e9f3458be98..8ac0e3fd470 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1126,6 +1126,18 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, Builder->getInt(RHSV ^ NotSignBit)); } } + + // (icmp ugt (xor X, C), ~C) -> (icmp ult X, C) + // iff -C is a power of 2 + if (ICI.getPredicate() == ICmpInst::ICMP_UGT && + XorCST->getValue() == ~RHSV && (RHSV + 1).isPowerOf2()) + return new ICmpInst(ICmpInst::ICMP_ULT, LHSI->getOperand(0), XorCST); + + // (icmp ult (xor X, C), -C) -> (icmp uge X, C) + // iff -C is a power of 2 + if (ICI.getPredicate() == ICmpInst::ICMP_ULT && + XorCST->getValue() == -RHSV && RHSV.isPowerOf2()) + return new ICmpInst(ICmpInst::ICMP_UGE, LHSI->getOperand(0), XorCST); } break; case Instruction::And: // (icmp pred (and X, AndCST), RHS) diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 5dccde26dd2..c541a695cd6 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -1181,3 +1181,21 @@ define i1 @icmp_and_X_-16_ne-16(i32 %X) { %cmp = icmp ne i32 %and, -16 ret i1 %cmp } + +; CHECK: @icmp_sub_-1_X_ult_4 +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %X, -5 +; CHECK-NEXT: ret i1 [[CMP]] +define i1 @icmp_sub_-1_X_ult_4(i32 %X) { + %sub = sub i32 -1, %X + %cmp = icmp ult i32 %sub, 4 + ret i1 %cmp +} + +; CHECK: @icmp_sub_-1_X_uge_4 +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, -4 +; CHECK-NEXT: ret i1 [[CMP]] +define i1 @icmp_sub_-1_X_uge_4(i32 %X) { + %sub = sub i32 -1, %X + %cmp = icmp uge i32 %sub, 4 + ret i1 %cmp +} -- 2.34.1