-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Reland: [InstCombine] Combine and->cmp->sel->or-disjoint into and->mul #142035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Change-Id: I389bba8bec937236e16eecc87688440878469472
Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
Co-authored-by: Yingwei Zheng <dtcxzyw@qq.com>
Change-Id: Id573c17c5abe064e75295ee8cf6d79fc0e71afad
Change-Id: I6642854a7a191ec364d4430ae70eeddf31f52685
Change-Id: I31eb218cdc295ccf5b2749b89945c95aed34d07f
@llvm/pr-subscribers-llvm-transforms Author: Jeffrey Byrnes (jrbyrnes) ChangesReland of #135274 The commit to land the original PR was blamelisted for two types of failures: https://lab.llvm.org/buildbot/#/builders/24/builds/8932 The second of which seems to be unrelated to the PR and seemingly fixed by 6ee2453 I've addressed the fix to the other issue with the latest commit in this PR b24f473 . This is the only difference between this PR and the previously accepted PR. Full diff: https://github.com/llvm/llvm-project/pull/142035.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index b74bce391aa56..49b2421fead57 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3641,6 +3641,52 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
foldAddLikeCommutative(I.getOperand(1), I.getOperand(0),
/*NSW=*/true, /*NUW=*/true))
return R;
+
+ Value *Cond0 = nullptr, *Cond1 = nullptr;
+ const APInt *Op0Eq = nullptr, *Op0Ne = nullptr;
+ const APInt *Op1Eq = nullptr, *Op1Ne = nullptr;
+
+ // (!(A & N) ? 0 : N * C) + (!(A & M) ? 0 : M * C) -> A & (N + M) * C
+ if (match(I.getOperand(0),
+ m_Select(m_Value(Cond0), m_APInt(Op0Eq), m_APInt(Op0Ne))) &&
+ match(I.getOperand(1),
+ m_Select(m_Value(Cond1), m_APInt(Op1Eq), m_APInt(Op1Ne)))) {
+
+ auto LHSDecompose =
+ decomposeBitTest(Cond0, /*LookThruTrunc=*/true,
+ /*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
+ auto RHSDecompose =
+ decomposeBitTest(Cond1, /*LookThruTrunc=*/true,
+ /*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
+
+ if (LHSDecompose && RHSDecompose && LHSDecompose->X == RHSDecompose->X &&
+ RHSDecompose->Mask.isPowerOf2() && LHSDecompose->Mask.isPowerOf2() &&
+ LHSDecompose->Mask != RHSDecompose->Mask &&
+ LHSDecompose->Mask.getBitWidth() == Op0Ne->getBitWidth() &&
+ RHSDecompose->Mask.getBitWidth() == Op1Ne->getBitWidth()) {
+ assert(Op0Ne->getBitWidth() == Op1Ne->getBitWidth());
+ assert(ICmpInst::isEquality(LHSDecompose->Pred));
+ if (LHSDecompose->Pred == ICmpInst::ICMP_NE)
+ std::swap(Op0Eq, Op0Ne);
+ if (RHSDecompose->Pred == ICmpInst::ICMP_NE)
+ std::swap(Op1Eq, Op1Ne);
+
+ if (!Op0Ne->isZero() && !Op1Ne->isZero() && Op0Eq->isZero() &&
+ Op1Eq->isZero() && Op0Ne->urem(LHSDecompose->Mask).isZero() &&
+ Op1Ne->urem(RHSDecompose->Mask).isZero() &&
+ Op0Ne->udiv(LHSDecompose->Mask) ==
+ Op1Ne->udiv(RHSDecompose->Mask)) {
+ auto NewAnd = Builder.CreateAnd(
+ LHSDecompose->X,
+ ConstantInt::get(LHSDecompose->X->getType(),
+ (LHSDecompose->Mask + RHSDecompose->Mask)));
+
+ return BinaryOperator::CreateMul(
+ NewAnd, ConstantInt::get(NewAnd->getType(),
+ Op0Ne->udiv(LHSDecompose->Mask)));
+ }
+ }
+ }
}
Value *X, *Y;
diff --git a/llvm/test/Transforms/InstCombine/or-bitmask.ll b/llvm/test/Transforms/InstCombine/or-bitmask.ll
new file mode 100644
index 0000000000000..3b482dc1794db
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/or-bitmask.ll
@@ -0,0 +1,366 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
+; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
+
+define i32 @add_select_cmp_and1(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and1(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and2(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and2(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 5
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 4
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 288
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and3(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and3(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[TEMP:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: [[BITOP2:%.*]] = and i32 [[IN]], 4
+; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[BITOP2]], 0
+; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 288
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TEMP]], [[SEL2]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %temp = or disjoint i32 %sel0, %sel1
+ %bitop2 = and i32 %in, 4
+ %cmp2 = icmp eq i32 %bitop2, 0
+ %sel2 = select i1 %cmp2, i32 0, i32 288
+ %out = or disjoint i32 %temp, %sel2
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and4(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and4(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[IN]], 12
+; CHECK-NEXT: [[TEMP3:%.*]] = mul nuw nsw i32 [[TMP2]], 72
+; CHECK-NEXT: [[OUT1:%.*]] = or disjoint i32 [[OUT]], [[TEMP3]]
+; CHECK-NEXT: ret i32 [[OUT1]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %temp = or disjoint i32 %sel0, %sel1
+ %bitop2 = and i32 %in, 4
+ %cmp2 = icmp eq i32 %bitop2, 0
+ %bitop3 = and i32 %in, 8
+ %cmp3 = icmp eq i32 %bitop3, 0
+ %sel2 = select i1 %cmp2, i32 0, i32 288
+ %sel3 = select i1 %cmp3, i32 0, i32 576
+ %temp2 = or disjoint i32 %sel2, %sel3
+ %out = or disjoint i32 %temp, %temp2
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_pred1(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_pred1(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp ne i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 72, i32 0
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_pred2(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_pred2(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp ne i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 144, i32 0
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_pred3(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_pred3(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp ne i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp ne i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 72, i32 0
+ %sel1 = select i1 %cmp1, i32 144, i32 0
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_trunc(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_trunc(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %cmp0 = trunc i32 %in to i1
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 72, i32 0
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_trunc1(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_trunc1(
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %cmp0 = trunc i32 %in to i1
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp ne i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 72, i32 0
+ %sel1 = select i1 %cmp1, i32 144, i32 0
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+
+define i32 @add_select_cmp_and_const_mismatch(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_const_mismatch(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 288
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 288
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_value_mismatch(i32 %in, i32 %in1) {
+; CHECK-LABEL: @add_select_cmp_and_value_mismatch(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN1:%.*]], 2
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 144
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in1, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_negative(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_negative(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[IN]], 2
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 -144
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, -2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 -144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+define i32 @add_select_cmp_and_bitsel_overlap(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_bitsel_overlap(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 2
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 144
+; CHECK-NEXT: ret i32 [[SEL0]]
+;
+ %bitop0 = and i32 %in, 2
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 144
+ %sel1 = select i1 %cmp1, i32 0, i32 144
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+; We cannot combine into and-mul, as %bitop1 may not be exactly 6
+
+define i32 @add_select_cmp_and_multbit_mask(i32 %in) {
+; CHECK-LABEL: @add_select_cmp_and_multbit_mask(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 6
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 432
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i32 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp eq i32 %bitop0, 0
+ %bitop1 = and i32 %in, 6
+ %cmp1 = icmp eq i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i32 0, i32 72
+ %sel1 = select i1 %cmp1, i32 0, i32 432
+ %out = or disjoint i32 %sel0, %sel1
+ ret i32 %out
+}
+
+
+define <2 x i32> @add_select_cmp_vec(<2 x i32> %in) {
+; CHECK-LABEL: @add_select_cmp_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 3)
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw <2 x i32> [[TMP1]], splat (i32 72)
+; CHECK-NEXT: ret <2 x i32> [[OUT]]
+;
+ %bitop0 = and <2 x i32> %in, <i32 1, i32 1>
+ %cmp0 = icmp eq <2 x i32> %bitop0, <i32 0, i32 0>
+ %bitop1 = and <2 x i32> %in, <i32 2, i32 2>
+ %cmp1 = icmp eq <2 x i32> %bitop1, <i32 0, i32 0>
+ %sel0 = select <2 x i1> %cmp0, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 72, i32 72>
+ %sel1 = select <2 x i1> %cmp1, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 144, i32 144>
+ %out = or disjoint <2 x i32> %sel0, %sel1
+ ret <2 x i32> %out
+}
+
+define <2 x i32> @add_select_cmp_vec_poison(<2 x i32> %in) {
+; CHECK-LABEL: @add_select_cmp_vec_poison(
+; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 1)
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
+; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], splat (i32 2)
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
+; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 poison, i32 144>
+; CHECK-NEXT: [[OUT:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> [[SEL1]], <2 x i32> <i32 72, i32 poison>
+; CHECK-NEXT: ret <2 x i32> [[OUT]]
+;
+ %bitop0 = and <2 x i32> %in, <i32 1, i32 1>
+ %cmp0 = icmp eq <2 x i32> %bitop0, <i32 0, i32 0>
+ %bitop1 = and <2 x i32> %in, <i32 2, i32 2>
+ %cmp1 = icmp eq <2 x i32> %bitop1, <i32 0, i32 0>
+ %sel0 = select <2 x i1> %cmp0, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 72, i32 poison>
+ %sel1 = select <2 x i1> %cmp1, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 poison, i32 144>
+ %out = or disjoint <2 x i32> %sel0, %sel1
+ ret <2 x i32> %out
+}
+
+define <2 x i32> @add_select_cmp_vec_nonunique(<2 x i32> %in) {
+; CHECK-LABEL: @add_select_cmp_vec_nonunique(
+; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], <i32 1, i32 2>
+; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
+; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], <i32 4, i32 8>
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
+; CHECK-NEXT: [[SEL0:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> zeroinitializer, <2 x i32> <i32 72, i32 144>
+; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 288, i32 576>
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint <2 x i32> [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret <2 x i32> [[OUT]]
+;
+ %bitop0 = and <2 x i32> %in, <i32 1, i32 2>
+ %cmp0 = icmp eq <2 x i32> %bitop0, <i32 0, i32 0>
+ %bitop1 = and <2 x i32> %in, <i32 4, i32 8>
+ %cmp1 = icmp eq <2 x i32> %bitop1, <i32 0, i32 0>
+ %sel0 = select <2 x i1> %cmp0, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 72, i32 144>
+ %sel1 = select <2 x i1> %cmp1, <2 x i32> <i32 0, i32 0>, <2 x i32> <i32 288, i32 576>
+ %out = or disjoint <2 x i32> %sel0, %sel1
+ ret <2 x i32> %out
+}
+
+define i64 @mask_select_types(i32 %in) {
+; CHECK-LABEL: @mask_select_types(
+; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
+; CHECK-NEXT: [[CMP0_NOT:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
+; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[BITOP1]], 0
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0_NOT]], i64 0, i64 72
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1_NOT]], i64 0, i64 144
+; CHECK-NEXT: [[OUT:%.*]] = or disjoint i64 [[SEL0]], [[SEL1]]
+; CHECK-NEXT: ret i64 [[OUT]]
+;
+ %bitop0 = and i32 %in, 1
+ %cmp0 = icmp ne i32 %bitop0, 0
+ %bitop1 = and i32 %in, 2
+ %cmp1 = icmp ne i32 %bitop1, 0
+ %sel0 = select i1 %cmp0, i64 72, i64 0
+ %sel1 = select i1 %cmp1, i64 144, i64 0
+ %out = or disjoint i64 %sel0, %sel1
+ ret i64 %out
+}
+
+define i64 @mask_select_types_1(i64 %in) {
+; CHECK-LABEL: @mask_select_types_1(
+; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[IN:%.*]], 3
+; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i64 [[TMP1]], 72
+; CHECK-NEXT: ret i64 [[OUT]]
+;
+ %bitop0 = and i64 %in, 1
+ %cmp0 = icmp ne i64 %bitop0, 0
+ %bitop1 = and i64 %in, 2
+ %cmp1 = icmp ne i64 %bitop1, 0
+ %sel0 = select i1 %cmp0, i64 72, i64 0
+ %sel1 = select i1 %cmp1, i64 144, i64 0
+ %out = or disjoint i64 %sel0, %sel1
+ ret i64 %out
+}
+
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CONSTSPLAT: {{.*}}
+; CONSTVEC: {{.*}}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
Reland of #135274
The commit to land the original PR was blamelisted for two types of failures:
https://lab.llvm.org/buildbot/#/builders/24/builds/8932
https://lab.llvm.org/buildbot/#/builders/198/builds/4844
The second of which seems to be unrelated to the PR and seemingly fixed by 6ee2453
I've addressed the fix to the other issue with the latest commit in this PR b24f473 . This is the only difference between this PR and the previously accepted PR.