[llvm] 82190f9 - [InstCombine] Fold icmp of select with implied condition

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri May 6 08:13:50 PDT 2022


Author: Nikita Popov
Date: 2022-05-06T17:13:32+02:00
New Revision: 82190f917ac4813e22a334b805e84dba8ed4f47d

URL: https://github.com/llvm/llvm-project/commit/82190f917ac4813e22a334b805e84dba8ed4f47d
DIFF: https://github.com/llvm/llvm-project/commit/82190f917ac4813e22a334b805e84dba8ed4f47d.diff

LOG: [InstCombine] Fold icmp of select with implied condition

When threading the icmp over the select, check whether the
condition can be folded when taking into account the select
condition.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/icmp-select.ll
    llvm/test/Transforms/InstCombine/minmax-fold.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 06e6f255bc7c4..4cc377c930c1b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3450,12 +3450,21 @@ Instruction *InstCombinerImpl::foldSelectICmp(ICmpInst::Predicate Pred,
                                               const ICmpInst &I) {
   // Try to fold the comparison into the select arms, which will cause the
   // select to be converted into a logical and/or.
+  auto SimplifyOp = [&](Value *Op, bool SelectCondIsTrue) -> Value * {
+    if (Value *Res = SimplifyICmpInst(Pred, Op, RHS, SQ))
+      return Res;
+    if (Optional<bool> Impl = isImpliedCondition(SI->getCondition(), Pred, Op,
+                                                 RHS, DL, SelectCondIsTrue))
+      return ConstantInt::get(I.getType(), *Impl);
+    return nullptr;
+  };
+
   ConstantInt *CI = nullptr;
-  Value *Op1 = SimplifyICmpInst(Pred, SI->getOperand(1), RHS, SQ);
+  Value *Op1 = SimplifyOp(SI->getOperand(1), true);
   if (Op1)
     CI = dyn_cast<ConstantInt>(Op1);
 
-  Value *Op2 = SimplifyICmpInst(Pred, SI->getOperand(2), RHS, SQ);
+  Value *Op2 = SimplifyOp(SI->getOperand(2), false);
   if (Op2)
     CI = dyn_cast<ConstantInt>(Op2);
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 3c6a74663512d..5332ef329090f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -166,8 +166,8 @@ define i1 @icmp_select_var_pred_uge_commuted(i8 %x, i8 %y, i8 %z) {
 define i1 @icmp_select_implied_cond(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_implied_cond(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 0, i8 [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp eq i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP21]]
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %cmp1 = icmp eq i8 %x, 0
@@ -178,9 +178,9 @@ define i1 @icmp_select_implied_cond(i8 %x, i8 %y) {
 
 define i1 @icmp_select_implied_cond_ne(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_implied_cond_ne(
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 0, i8 [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[CMP1]], i1 [[CMP21]], i1 false
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %cmp1 = icmp eq i8 %x, 0
@@ -192,8 +192,8 @@ define i1 @icmp_select_implied_cond_ne(i8 %x, i8 %y) {
 define i1 @icmp_select_implied_cond_swapped_select(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_implied_cond_swapped_select(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 [[Y:%.*]], i8 0
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp eq i8 [[Y:%.*]], 0
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[CMP1]], i1 [[CMP21]], i1 false
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %cmp1 = icmp eq i8 %x, 0
@@ -206,8 +206,9 @@ define i1 @icmp_select_implied_cond_swapped_select_with_inv_cond(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_implied_cond_swapped_select_with_inv_cond(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
 ; CHECK-NEXT:    call void @use.i1(i1 [[CMP1]])
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 [[Y:%.*]], i8 0
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp eq i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[NOT_CMP1:%.*]] = xor i1 [[CMP1]], true
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[NOT_CMP1]], i1 true, i1 [[CMP21]]
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %cmp1 = icmp ne i8 %x, 0
@@ -220,8 +221,8 @@ define i1 @icmp_select_implied_cond_swapped_select_with_inv_cond(i8 %x, i8 %y) {
 define i1 @icmp_select_implied_cond_relational(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_implied_cond_relational(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i8 [[X:%.*]], 10
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 10, i8 [[Y:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp ult i8 [[Y:%.*]], [[X]]
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP21]]
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %cmp1 = icmp ugt i8 %x, 10
@@ -247,10 +248,9 @@ define i1 @icmp_select_implied_cond_relational_off_by_one(i8 %x, i8 %y) {
 
 define i1 @umin_seq_comparison(i8 %x, i8 %y) {
 ; CHECK-LABEL: @umin_seq_comparison(
-; CHECK-NEXT:    [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[X:%.*]], i8 [[Y:%.*]])
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X]], 0
-; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i8 0, i8 [[MIN]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i8 [[SEL]], [[X]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[CMP21:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
+; CHECK-NEXT:    [[CMP2:%.*]] = select i1 [[CMP1]], i1 true, i1 [[CMP21]]
 ; CHECK-NEXT:    ret i1 [[CMP2]]
 ;
   %min = call i8 @llvm.umin.i8(i8 %x, i8 %y)

diff  --git a/llvm/test/Transforms/InstCombine/minmax-fold.ll b/llvm/test/Transforms/InstCombine/minmax-fold.ll
index 1f05370852d59..a3119d0726f06 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fold.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fold.ll
@@ -99,8 +99,8 @@ define i32 @t8(i64 %a, i32 %b) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 -32767)
 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[B:%.*]], 42
-; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i32 42, i32 [[TMP2]]
-; CHECK-NEXT:    [[TMP5:%.*]] = icmp ne i32 [[TMP4]], [[B]]
+; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i32 [[TMP2]], [[B]]
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP3]], i1 true, i1 [[TMP4]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = zext i1 [[TMP5]] to i32
 ; CHECK-NEXT:    ret i32 [[TMP6]]
 ;


        


More information about the llvm-commits mailing list