aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2024-04-04 21:07:37 -0500
committerNoah Goldstein <goldstein.w.n@gmail.com>2024-04-09 15:38:18 -0500
commit71ef04d7cd6c0d6133ab11ca4cfceefe506a1acb (patch)
treed25d207e11c178983118c2e68f3edc4db1986cef
parent5b58eb68ed36717971970f35a1192213e3eb4ec5 (diff)
downloadllvm-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.cpp11
-rw-r--r--llvm/test/Transforms/InstCombine/icmp-or.ll7
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]]
;