[llvm] [InstCombine] Improve select simplification based on known bits (PR #97289)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 06:02:03 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

<details>
<summary>Changes</summary>

https://github.com/llvm/llvm-project/pull/95923 added support to simplify select arms based on known bits implied by the select condition. That PR was limited to the case where the arm folds to a constant.

This PR extends support to the case where the select arm simplifies in some other way, for example by removing a bitwise operation. This is done by calling SimplifyDemandedBits() with the adjusted SimplifyQuery.

Unfortunately, this case requires that the condition isn't undef.

Compile-time: http://llvm-compile-time-tracker.com/compare.php?from=11484cb817bcc2a6e2ef9572be982a1a5a4964ec&to=67da0f88b52c613a277f93cb8d0183939786a9c7&stat=instructions%3Au

Fixes https://github.com/llvm/llvm-project/issues/71533.

---
Full diff: https://github.com/llvm/llvm-project/pull/97289.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+28-14) 
- (modified) llvm/test/Transforms/InstCombine/select.ll (+4-7) 


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 979495dae853e..fbbe2251b97e6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4052,22 +4052,36 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
     });
     SimplifyQuery Q = SQ.getWithInstruction(&SI).getWithCondContext(CC);
     if (!CC.AffectedValues.empty()) {
-      if (!isa<Constant>(TrueVal) &&
-          hasAffectedValue(TrueVal, CC.AffectedValues, /*Depth=*/0)) {
-        KnownBits Known = llvm::computeKnownBits(TrueVal, /*Depth=*/0, Q);
-        if (Known.isConstant())
-          return replaceOperand(SI, 1,
-                                ConstantInt::get(SelType, Known.getConstant()));
-      }
+      std::optional<bool> NotUndef;
+      auto SimplifyOp = [&](unsigned OpNum) -> Instruction * {
+        Value *V = SI.getOperand(OpNum);
+        if (isa<Constant>(V) ||
+            !hasAffectedValue(V, CC.AffectedValues, /*Depth=*/0))
+          return nullptr;
+
+        if (!NotUndef)
+          NotUndef = isGuaranteedNotToBeUndef(CondVal);
 
+        if (*NotUndef) {
+          unsigned BitWidth = SelType->getScalarSizeInBits();
+          KnownBits Known(BitWidth);
+          if (SimplifyDemandedBits(&SI, OpNum, APInt::getAllOnes(BitWidth),
+                                   Known, /*Depth=*/0, Q))
+            return &SI;
+        } else {
+          KnownBits Known = llvm::computeKnownBits(V, /*Depth=*/0, Q);
+          if (Known.isConstant())
+            return replaceOperand(
+                SI, OpNum, ConstantInt::get(SelType, Known.getConstant()));
+        }
+        return nullptr;
+      };
+
+      if (Instruction *Res = SimplifyOp(1))
+        return Res;
       CC.Invert = true;
-      if (!isa<Constant>(FalseVal) &&
-          hasAffectedValue(FalseVal, CC.AffectedValues, /*Depth=*/0)) {
-        KnownBits Known = llvm::computeKnownBits(FalseVal, /*Depth=*/0, Q);
-        if (Known.isConstant())
-          return replaceOperand(SI, 2,
-                                ConstantInt::get(SelType, Known.getConstant()));
-      }
+      if (Instruction *Res = SimplifyOp(2))
+        return Res;
     }
   }
 
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 63a4f74cbaaea..29805e07d0ac9 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -2989,9 +2989,8 @@ define i8 @select_replacement_loop3(i32 noundef %x) {
 
 define i16 @select_replacement_loop4(i16 noundef %p_12) {
 ; CHECK-LABEL: @select_replacement_loop4(
-; CHECK-NEXT:    [[AND1:%.*]] = and i16 [[P_12:%.*]], 1
-; CHECK-NEXT:    [[CMP21:%.*]] = icmp ult i16 [[P_12]], 2
-; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[CMP21]], i16 [[AND1]], i16 0
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i16 [[P_12:%.*]], 2
+; CHECK-NEXT:    [[AND3:%.*]] = select i1 [[CMP1]], i16 [[P_12]], i16 0
 ; CHECK-NEXT:    ret i16 [[AND3]]
 ;
   %cmp1 = icmp ult i16 %p_12, 2
@@ -4671,8 +4670,7 @@ define i8 @select_knownbits_simplify(i8 noundef %x)  {
 ; CHECK-LABEL: @select_knownbits_simplify(
 ; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X:%.*]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -2
-; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
+; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[X]], i8 0
 ; CHECK-NEXT:    ret i8 [[RES]]
 ;
   %x.lo = and i8 %x, 1
@@ -4686,8 +4684,7 @@ define i8 @select_knownbits_simplify_nested(i8 noundef %x)  {
 ; CHECK-LABEL: @select_knownbits_simplify_nested(
 ; CHECK-NEXT:    [[X_LO:%.*]] = and i8 [[X:%.*]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
-; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -2
-; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
+; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X]], [[X]]
 ; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
 ; CHECK-NEXT:    ret i8 [[RES]]
 ;

``````````

</details>


https://github.com/llvm/llvm-project/pull/97289


More information about the llvm-commits mailing list