[PATCH] D140666: [InstCombine] combine intersection for inequality icmps
Yingchi Long via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 25 02:29:52 PST 2023
inclyc updated this revision to Diff 492043.
inclyc added a comment.
add test `masked_and_expected_false`
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D140666/new/
https://reviews.llvm.org/D140666
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/icmp-logical.ll
Index: llvm/test/Transforms/InstCombine/icmp-logical.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-logical.ll
+++ llvm/test/Transforms/InstCombine/icmp-logical.ll
@@ -280,11 +280,8 @@
define i1 @masked_or_eq(i32 %A) {
; CHECK-LABEL: @masked_or_eq(
-; CHECK-NEXT: [[MASK1:%.*]] = and i32 [[A:%.*]], 15
-; CHECK-NEXT: [[TST1:%.*]] = icmp eq i32 [[MASK1]], 3
-; CHECK-NEXT: [[MASK2:%.*]] = and i32 [[A]], 255
-; CHECK-NEXT: [[TST2:%.*]] = icmp eq i32 [[MASK2]], 243
-; CHECK-NEXT: [[RES:%.*]] = or i1 [[TST1]], [[TST2]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[TMP1]], 3
; CHECK-NEXT: ret i1 [[RES]]
;
%mask1 = and i32 %A, 15 ; 0x0f
@@ -314,11 +311,8 @@
define i1 @masked_and_ne(i32 %A) {
; CHECK-LABEL: @masked_and_ne(
-; CHECK-NEXT: [[MASK1:%.*]] = and i32 [[A:%.*]], 15
-; CHECK-NEXT: [[TST1:%.*]] = icmp ne i32 [[MASK1]], 3
-; CHECK-NEXT: [[MASK2:%.*]] = and i32 [[A]], 255
-; CHECK-NEXT: [[TST2:%.*]] = icmp ne i32 [[MASK2]], 243
-; CHECK-NEXT: [[RES:%.*]] = and i1 [[TST1]], [[TST2]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT: [[RES:%.*]] = icmp ne i32 [[TMP1]], 3
; CHECK-NEXT: ret i1 [[RES]]
;
%mask1 = and i32 %A, 15 ; 0x0f
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -654,6 +654,41 @@
return Builder.CreateICmp(NewCC, NewAnd, NewOr2);
}
+ if (Mask & BMask_NotMixed) {
+ // Check the intersection (B & D) for inequality.
+ // Assume that (B & D) == B || (B & D) == D, i.e B/D is a subset of D/B
+ // and (B & D) & (C ^ E) == 0, bits of C and E, which are shared by both the
+ // B and the D, don't contradict.
+ // Note that we can assume (~B & C) == 0 && (~D & E) == 0, previous
+ // operation should delete these icmps if it hadn't been met.
+
+ // (icmp ne (A & B), C) & (icmp ne (A & D), E)
+ // -> (icmp ne (A & (B & D)), (C & E))
+
+ NewCC = CmpInst::getInversePredicate(NewCC);
+
+ const APInt *OldConstC, *OldConstE;
+ if (!match(C, m_APInt(OldConstC)) || !match(E, m_APInt(OldConstE)))
+ return nullptr;
+
+ const APInt ConstC = PredL != NewCC ? *ConstB ^ *OldConstC : *OldConstC;
+ const APInt ConstE = PredR != NewCC ? *ConstD ^ *OldConstE : *OldConstE;
+
+ const APInt ConstT = *ConstB & *ConstD;
+ if (ConstT != *ConstB && ConstT != *ConstD)
+ return nullptr;
+
+ assert((~*ConstB & ConstC) == 0);
+ assert((~*ConstD & ConstE) == 0);
+
+ // If there is a conflict, we still have to check both sides.
+ if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
+ return nullptr;
+
+ Value *NewAnd1 = Builder.CreateAnd(A, /* B&D */ ConstT);
+ Value *NewAnd2 = ConstantInt::get(A->getType(), ConstC & ConstE);
+ return Builder.CreateICmp(NewCC, NewAnd1, NewAnd2);
+ }
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140666.492043.patch
Type: text/x-patch
Size: 3126 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230125/7358c1ca/attachment.bin>
More information about the llvm-commits
mailing list