[llvm] 90dba83 - [InstCombine] Fold or of icmp ne trunc/and
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 28 06:07:24 PDT 2022
Author: Nikita Popov
Date: 2022-04-28T15:07:16+02:00
New Revision: 90dba831ae50f2c3dc5de1029b1821790411ca9a
URL: https://github.com/llvm/llvm-project/commit/90dba831ae50f2c3dc5de1029b1821790411ca9a
DIFF: https://github.com/llvm/llvm-project/commit/90dba831ae50f2c3dc5de1029b1821790411ca9a.diff
LOG: [InstCombine] Fold or of icmp ne trunc/and
This adds the de Morgan conjugated variant for the existing
"and eq" style fold.
Proof: https://alive2.llvm.org/ce/z/tkNAcG
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/merge-icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 8c25d4992f736..bd910fcde734b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2550,10 +2550,11 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
return nullptr;
// (trunc x) == C1 & (and x, CA) == C2 -> (and x, CA|CMAX) == C1|C2
+ // (trunc x) != C1 | (and x, CA) != C2 -> (and x, CA|CMAX) != C1|C2
// where CMAX is the all ones value for the truncated type,
// iff the lower bits of C2 and CA are zero.
- if (IsAnd && PredL == ICmpInst::ICMP_EQ && PredL == PredR &&
- LHS->hasOneUse() && RHS->hasOneUse()) {
+ if (PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) &&
+ PredL == PredR && LHS->hasOneUse() && RHS->hasOneUse()) {
Value *V;
const APInt *AndC, *SmallC = nullptr, *BigC = nullptr;
diff --git a/llvm/test/Transforms/InstCombine/merge-icmp.ll b/llvm/test/Transforms/InstCombine/merge-icmp.ll
index 4ca63cd3441dd..aaecdf8e184a4 100644
--- a/llvm/test/Transforms/InstCombine/merge-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/merge-icmp.ll
@@ -97,12 +97,8 @@ define <2 x i1> @and_test2_vector(<2 x i16>* %x) {
define i1 @or_basic(i16 %load) {
; CHECK-LABEL: @or_basic(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i16 [[LOAD:%.*]], 17791
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%trunc = trunc i16 %load to i8
%cmp1 = icmp ne i8 %trunc, 127
@@ -114,12 +110,8 @@ define i1 @or_basic(i16 %load) {
define i1 @or_basic_commuted(i16 %load) {
; CHECK-LABEL: @or_basic_commuted(
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD:%.*]], -256
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i16 [[AND]], 32512
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD]] to i8
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[TRUNC]], 69
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i16 [[LOAD:%.*]], 32581
+; CHECK-NEXT: ret i1 [[TMP1]]
;
%and = and i16 %load, -256
%cmp1 = icmp ne i16 %and, 32512
@@ -131,12 +123,8 @@ define i1 @or_basic_commuted(i16 %load) {
define <2 x i1> @or_vector(<2 x i16> %load) {
; CHECK-LABEL: @or_vector(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc <2 x i16> [[LOAD:%.*]] to <2 x i8>
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne <2 x i8> [[TRUNC]], <i8 127, i8 127>
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i16> [[LOAD]], <i16 -256, i16 -256>
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne <2 x i16> [[AND]], <i16 17664, i16 17664>
-; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i16> [[LOAD:%.*]], <i16 17791, i16 17791>
+; CHECK-NEXT: ret <2 x i1> [[TMP1]]
;
%trunc = trunc <2 x i16> %load to <2 x i8>
%cmp1 = icmp ne <2 x i8> %trunc, <i8 127, i8 127>
@@ -148,12 +136,9 @@ define <2 x i1> @or_vector(<2 x i16> %load) {
define i1 @or_nontrivial_mask1(i16 %load) {
; CHECK-LABEL: @or_nontrivial_mask1(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], 3840
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 1280
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], 4095
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i16 [[TMP1]], 1407
+; CHECK-NEXT: ret i1 [[TMP2]]
;
%trunc = trunc i16 %load to i8
%cmp1 = icmp ne i8 %trunc, 127
@@ -165,12 +150,9 @@ define i1 @or_nontrivial_mask1(i16 %load) {
define i1 @or_nontrivial_mask2(i16 %load) {
; CHECK-LABEL: @or_nontrivial_mask2(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], -3841
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i16 [[TMP1]], 20607
+; CHECK-NEXT: ret i1 [[TMP2]]
;
%trunc = trunc i16 %load to i8
%cmp1 = icmp ne i8 %trunc, 127
@@ -222,11 +204,9 @@ define i1 @or_extra_use3(i16 %load) {
; CHECK-LABEL: @or_extra_use3(
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
; CHECK-NEXT: call void @use.i8(i8 [[TRUNC]])
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i16 [[TMP1]], 20607
+; CHECK-NEXT: ret i1 [[TMP2]]
;
%trunc = trunc i16 %load to i8
call void @use.i8(i8 %trunc)
@@ -239,13 +219,11 @@ define i1 @or_extra_use3(i16 %load) {
define i1 @or_extra_use4(i16 %load) {
; CHECK-LABEL: @or_extra_use4(
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096
+; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD:%.*]], -4096
; CHECK-NEXT: call void @use.i16(i16 [[AND]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
-; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i16 [[TMP1]], 20607
+; CHECK-NEXT: ret i1 [[TMP2]]
;
%trunc = trunc i16 %load to i8
%cmp1 = icmp ne i8 %trunc, 127
More information about the llvm-commits
mailing list