[llvm] [InstCombine] fold `(icmp eq/ne (or disjoint x, C0), C1)` -> `(icmp eq/ne x, C0^C1)` (PR #87734)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 9 11:07:20 PDT 2024
https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/87734
>From f43498681e491a6d977602257d30d3c375fbeeee Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 4 Apr 2024 21:07:34 -0500
Subject: [PATCH 1/2] [InstCombine] Add tests for folding `(icmp eq/ne (or
disjoint x, C0), C1)`; NFC
---
llvm/test/Transforms/InstCombine/icmp-or.ll | 50 +++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/icmp-or.ll b/llvm/test/Transforms/InstCombine/icmp-or.ll
index 922845c1e7e2d8..ce6ebfc1965543 100644
--- a/llvm/test/Transforms/InstCombine/icmp-or.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-or.ll
@@ -951,3 +951,53 @@ define i1 @icmp_or_xor_with_sub_3_6(i64 %x1, i64 %y1, i64 %x2, i64 %y2, i64 %x3,
%cmp = icmp eq i64 %or1, 0
ret i1 %cmp
}
+
+
+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: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 1
+ %cmp = icmp eq i8 %or, 19
+ ret i1 %cmp
+}
+
+
+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: call void @use(i8 [[OR]])
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 5
+ %cmp = icmp ne i8 %or, 71
+ call void @use(i8 %or)
+ ret i1 %cmp
+}
+
+
+define i1 @or_disjoint_with_constants_fail_missing_const1(i8 %x, i8 %y) {
+; CHECK-LABEL: @or_disjoint_with_constants_fail_missing_const1(
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], 19
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, %y
+ %cmp = icmp eq i8 %or, 19
+ ret i1 %cmp
+}
+
+define i1 @or_disjoint_with_constants_fail_missing_const2(i8 %x, i8 %y) {
+; CHECK-LABEL: @or_disjoint_with_constants_fail_missing_const2(
+; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[X:%.*]], 19
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], [[Y:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %or = or disjoint i8 %x, 19
+ %cmp = icmp eq i8 %or, %y
+ ret i1 %cmp
+}
+
>From 4cb341df9904069f6c9ba9a142859de64065f6ed Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 4 Apr 2024 21:07:37 -0500
Subject: [PATCH 2/2] [InstCombine] fold `(icmp eq/ne (or disjoint x, C0), C1)`
-> `(icmp eq/ne x, C0^C1)`
Proof: https://alive2.llvm.org/ce/z/m3xoo_
---
.../Transforms/InstCombine/InstCombineCompares.cpp | 11 +++++++++++
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 db302d7e526844..756bf718c8b577 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 ce6ebfc1965543..1f9db5e5db9aad 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]]
;
More information about the llvm-commits
mailing list