[llvm] Fold select i cmp and bin op (PR #219676)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 29 05:13:01 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Andreas Jonson (andjo403)
<details>
<summary>Changes</summary>
avoids regression seen in https://github.com/llvm/llvm-project/pull/184182/changes#diff-47b908b9c27dfb9833310855fd957b4c8f43302b1d72983086e345a95a5b1dd5R1655
when the created shl shifts out all but one bit the and with one is not needed.
proof: https://alive2.llvm.org/ce/z/MQYp6f
---
Full diff: https://github.com/llvm/llvm-project/pull/219676.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+4)
- (modified) llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll (+26)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 090abfaea28ec..f785ea182a389 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -928,6 +928,10 @@ static Value *foldSelectICmpAndBinOp(Value *CondVal, Value *TrueVal,
bool NeedZExtTrunc = Y->getType()->getScalarSizeInBits() !=
V->getType()->getScalarSizeInBits();
+ // the demanded bits for the created shl make the and redundant
+ if (AndMask.isOne() && C2->isSignBitSet())
+ CreateAnd = false;
+
// Make sure we don't create more instructions than we save.
if ((NeedShift + NeedXor + NeedZExtTrunc + CreateAnd) >
(CondVal->hasOneUse() + BinOp->hasOneUse()))
diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
index 771fad66e961e..5240a837bf014 100644
--- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
+++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
@@ -1765,6 +1765,32 @@ define i8 @select_trunc_or_2(i8 %x, i8 %y) {
ret i8 %select
}
+define i16 @select_trunc_or_signbit(i8 %x, i16 %y) {
+; CHECK-LABEL: @select_trunc_or_signbit(
+; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
+; CHECK-NEXT: [[TMP2:%.*]] = shl i16 [[TMP1]], 15
+; CHECK-NEXT: [[SELECT:%.*]] = or i16 [[Y:%.*]], [[TMP2]]
+; CHECK-NEXT: ret i16 [[SELECT]]
+;
+ %trunc = trunc i8 %x to i1
+ %or = or i16 %y, -32768
+ %select = select i1 %trunc, i16 %or, i16 %y
+ ret i16 %select
+}
+
+define i16 @neg_select_trunc_or_not_signbit(i8 %x, i16 %y) {
+; CHECK-LABEL: @neg_select_trunc_or_not_signbit(
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: [[OR:%.*]] = or i16 [[Y:%.*]], 16384
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i16 [[OR]], i16 [[Y]]
+; CHECK-NEXT: ret i16 [[SELECT]]
+;
+ %trunc = trunc i8 %x to i1
+ %or = or i16 %y, 16384
+ %select = select i1 %trunc, i16 %or, i16 %y
+ ret i16 %select
+}
+
define i8 @select_not_trunc_or_2(i8 %x, i8 %y) {
; CHECK-LABEL: @select_not_trunc_or_2(
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
``````````
</details>
https://github.com/llvm/llvm-project/pull/219676
More information about the llvm-commits
mailing list