[llvm] InstCombine/Select: remove redundant code (NFC) (PR #112388)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 15 09:15:59 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Ramkumar Ramachandra (artagnon)
<details>
<summary>Changes</summary>
InstCombinerImpl::foldSelectInstWithICmp has some inlined code for select-icmp-xor simplification, but this simplification is already done by other code. Cover the cases that it claims to simplify, and demonstrate that stripping it doesn't cause test changes.
---
Full diff: https://github.com/llvm/llvm-project/pull/112388.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (-50)
- (added) llvm/test/Transforms/InstCombine/select-icmp-xor.ll (+190)
``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 820d3608c8dc49..39a6e8e191eb28 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1953,56 +1953,6 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
return &SI;
}
- // FIXME: This code is nearly duplicated in InstSimplify. Using/refactoring
- // decomposeBitTestICmp() might help.
- if (TrueVal->getType()->isIntOrIntVectorTy()) {
- unsigned BitWidth =
- DL.getTypeSizeInBits(TrueVal->getType()->getScalarType());
- APInt MinSignedValue = APInt::getSignedMinValue(BitWidth);
- Value *X;
- const APInt *Y, *C;
- bool TrueWhenUnset;
- bool IsBitTest = false;
- if (ICmpInst::isEquality(Pred) &&
- match(CmpLHS, m_And(m_Value(X), m_Power2(Y))) &&
- match(CmpRHS, m_Zero())) {
- IsBitTest = true;
- TrueWhenUnset = Pred == ICmpInst::ICMP_EQ;
- } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
- X = CmpLHS;
- Y = &MinSignedValue;
- IsBitTest = true;
- TrueWhenUnset = false;
- } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
- X = CmpLHS;
- Y = &MinSignedValue;
- IsBitTest = true;
- TrueWhenUnset = true;
- }
- if (IsBitTest) {
- Value *V = nullptr;
- // (X & Y) == 0 ? X : X ^ Y --> X & ~Y
- if (TrueWhenUnset && TrueVal == X &&
- match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
- V = Builder.CreateAnd(X, ~(*Y));
- // (X & Y) != 0 ? X ^ Y : X --> X & ~Y
- else if (!TrueWhenUnset && FalseVal == X &&
- match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
- V = Builder.CreateAnd(X, ~(*Y));
- // (X & Y) == 0 ? X ^ Y : X --> X | Y
- else if (TrueWhenUnset && FalseVal == X &&
- match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
- V = Builder.CreateOr(X, *Y);
- // (X & Y) != 0 ? X : X ^ Y --> X | Y
- else if (!TrueWhenUnset && TrueVal == X &&
- match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
- V = Builder.CreateOr(X, *Y);
-
- if (V)
- return replaceInstUsesWith(SI, V);
- }
- }
-
if (Instruction *V =
foldSelectICmpAndAnd(SI.getType(), ICI, TrueVal, FalseVal, Builder))
return V;
diff --git a/llvm/test/Transforms/InstCombine/select-icmp-xor.ll b/llvm/test/Transforms/InstCombine/select-icmp-xor.ll
new file mode 100644
index 00000000000000..c8ce114a683eee
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/select-icmp-xor.ll
@@ -0,0 +1,190 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=instcombine -S %s | FileCheck %s
+
+define i8 @select_icmp_eq_pow2(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_eq_pow2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = and i8 [[X]], -5
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 4
+ %icmp = icmp eq i8 %and, 0
+ %xor = xor i8 %x, 4
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_eq_pow2_flipped(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_eq_pow2_flipped(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = or i8 [[X]], 4
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 4
+ %icmp = icmp eq i8 %and, 0
+ %xor = xor i8 %x, 4
+ %sel = select i1 %icmp, i8 %xor, i8 %x
+ ret i8 %sel
+}
+
+define i8 @select_icmp_eq_not_pow2(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_eq_not_pow2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 5
+; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i8 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], 5
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP]], i8 [[X]], i8 [[XOR]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 5
+ %icmp = icmp eq i8 %and, 0
+ %xor = xor i8 %x, 5
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_ne_pow2(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_ne_pow2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = and i8 [[X]], -5
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 4
+ %icmp = icmp ne i8 %and, 0
+ %xor = xor i8 %x, 4
+ %sel = select i1 %icmp, i8 %xor, i8 %x
+ ret i8 %sel
+}
+
+define i8 @select_icmp_ne_pow2_flipped(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_ne_pow2_flipped(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = or i8 [[X]], 4
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 4
+ %icmp = icmp ne i8 %and, 0
+ %xor = xor i8 %x, 4
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_ne_not_pow2(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_ne_not_pow2(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 5
+; CHECK-NEXT: [[ICMP_NOT:%.*]] = icmp eq i8 [[AND]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], 5
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP_NOT]], i8 [[X]], i8 [[XOR]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %and = and i8 %x, 5
+ %icmp = icmp ne i8 %and, 0
+ %xor = xor i8 %x, 5
+ %sel = select i1 %icmp, i8 %xor, i8 %x
+ ret i8 %sel
+}
+
+define i8 @select_icmp_slt_zero_smin(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_slt_zero_smin(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = or i8 [[X]], -128
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp slt i8 %x, 0
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_slt_zero_smin_flipped(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_slt_zero_smin_flipped(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = and i8 [[X]], 127
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp slt i8 %x, 0
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %xor, i8 %x
+ ret i8 %sel
+}
+
+define i8 @select_icmp_slt_not_zero(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_slt_not_zero(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ICMP:%.*]] = icmp slt i8 [[X]], 1
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], -128
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP]], i8 [[X]], i8 [[XOR]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp slt i8 %x, 1
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_slt_not_smin(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_slt_not_smin(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ICMP:%.*]] = icmp slt i8 [[X]], 0
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], -127
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP]], i8 [[X]], i8 [[XOR]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp slt i8 %x, 0
+ %xor = xor i8 %x, -127
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_sgt_allones_smin(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_sgt_allones_smin(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = and i8 [[X]], 127
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp sgt i8 %x, 255
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_sgt_allones_smin_flipped(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_sgt_allones_smin_flipped(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[SEL:%.*]] = or i8 [[X]], -128
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp sgt i8 %x, 255
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %xor, i8 %x
+ ret i8 %sel
+}
+
+define i8 @select_icmp_sgt_not_allones(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_sgt_not_allones(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[ICMP:%.*]] = icmp sgt i8 [[X]], -2
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], -128
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP]], i8 [[X]], i8 [[XOR]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp sgt i8 %x, 254
+ %xor = xor i8 %x, -128
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
+
+define i8 @select_icmp_sgt_not_smin(i8 %x) {
+; CHECK-LABEL: define i8 @select_icmp_sgt_not_smin(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X]], -127
+; CHECK-NEXT: [[ICMP1:%.*]] = icmp slt i8 [[X]], 0
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[ICMP1]], i8 [[XOR]], i8 [[X]]
+; CHECK-NEXT: ret i8 [[SEL]]
+;
+ %icmp = icmp sgt i8 %x, 255
+ %xor = xor i8 %x, -127
+ %sel = select i1 %icmp, i8 %x, i8 %xor
+ ret i8 %sel
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/112388
More information about the llvm-commits
mailing list