[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