diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-04-04 21:07:37 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2024-04-09 15:38:18 -0500 |
commit | 71ef04d7cd6c0d6133ab11ca4cfceefe506a1acb (patch) | |
tree | d25d207e11c178983118c2e68f3edc4db1986cef | |
parent | 5b58eb68ed36717971970f35a1192213e3eb4ec5 (diff) | |
download | llvm-71ef04d7cd6c0d6133ab11ca4cfceefe506a1acb.zip llvm-71ef04d7cd6c0d6133ab11ca4cfceefe506a1acb.tar.gz llvm-71ef04d7cd6c0d6133ab11ca4cfceefe506a1acb.tar.bz2 |
[InstCombine] fold `(icmp eq/ne (or disjoint x, C0), C1)` -> `(icmp eq/ne x, C0^C1)`
Proof: https://alive2.llvm.org/ce/z/m3xoo_
Closes #87734
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 11 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/icmp-or.ll | 7 |
2 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 53aa84d..9ff1e3a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -23,6 +23,7 @@ #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/InstrTypes.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/PatternMatch.h" #include "llvm/Support/KnownBits.h" @@ -2049,6 +2050,16 @@ Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp, } Value *OrOp0 = Or->getOperand(0), *OrOp1 = Or->getOperand(1); + + // (icmp eq/ne (or disjoint x, C0), C1) + // -> (icmp eq/ne x, C0^C1) + if (Cmp.isEquality() && match(OrOp1, m_ImmConstant()) && + cast<PossiblyDisjointInst>(Or)->isDisjoint()) { + Value *NewC = + Builder.CreateXor(OrOp1, ConstantInt::get(OrOp1->getType(), C)); + return new ICmpInst(Pred, OrOp0, NewC); + } + const APInt *MaskC; if (match(OrOp1, m_APInt(MaskC)) && Cmp.isEquality()) { if (*MaskC == C && (C + 1).isPowerOf2()) { diff --git a/llvm/test/Transforms/InstCombine/icmp-or.ll b/llvm/test/Transforms/InstCombine/icmp-or.ll index ce6ebfc..1f9db5e 100644 --- a/llvm/test/Transforms/InstCombine/icmp-or.ll +++ b/llvm/test/Transforms/InstCombine/icmp-or.ll @@ -955,8 +955,7 @@ define i1 @icmp_or_xor_with_sub_3_6(i64 %x1, i64 %y1, i64 %x2, i64 %y2, i64 %x3, define i1 @or_disjoint_with_constants(i8 %x) { ; CHECK-LABEL: @or_disjoint_with_constants( -; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -2 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 18 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1:%.*]], 18 ; CHECK-NEXT: ret i1 [[CMP]] ; %or = or disjoint i8 %x, 1 @@ -967,8 +966,8 @@ define i1 @or_disjoint_with_constants(i8 %x) { define i1 @or_disjoint_with_constants2(i8 %x) { ; CHECK-LABEL: @or_disjoint_with_constants2( -; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], 5 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[OR]], 71 +; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[TMP1:%.*]], 5 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[TMP1]], 66 ; CHECK-NEXT: call void @use(i8 [[OR]]) ; CHECK-NEXT: ret i1 [[CMP]] ; |